Moved handleMaterialSFX to updateGraphics(), which removes the need

for a isLastSubstep() function in main(). Fix potential bug when
a new material sfx is triggered when a previous sfx still exists.
This commit is contained in:
hiker 2018-04-30 08:49:57 +10:00
parent a737f9e3d5
commit 28eb0112e0
3 changed files with 36 additions and 21 deletions

View File

@ -197,6 +197,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
m_skid_sound = SFXManager::get()->createSoundSource( "skid" ); m_skid_sound = SFXManager::get()->createSoundSource( "skid" );
m_nitro_sound = SFXManager::get()->createSoundSource( "nitro" ); m_nitro_sound = SFXManager::get()->createSoundSource( "nitro" );
m_terrain_sound = NULL; m_terrain_sound = NULL;
m_last_sound_material = NULL;
m_previous_terrain_sound = NULL; m_previous_terrain_sound = NULL;
} // Kart } // Kart
@ -1202,7 +1203,8 @@ float Kart::getShieldTime() const
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Decreases the kart's shield time. * Decreases the kart's shield time.
* \param t The time substracted from the shield timer. If t == 0.0f, the default amout of time is substracted. * \param t The time substracted from the shield timer. If t == 0.0f, the
default amout of time is substracted.
*/ */
void Kart::decreaseShieldTime() void Kart::decreaseShieldTime()
{ {
@ -1583,7 +1585,6 @@ void Kart::update(int ticks)
} }
body->setGravity(gravity); body->setGravity(gravity);
} // if !flying } // if !flying
handleMaterialSFX(material);
if (material->isDriveReset() && isOnGround()) if (material->isDriveReset() && isOnGround())
{ {
new RescueAnimation(this); new RescueAnimation(this);
@ -1777,7 +1778,7 @@ void Kart::setSquash(float time, float slowdown)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Plays any terrain specific sound effect. /** Plays any terrain specific sound effect.
*/ */
void Kart::handleMaterialSFX(const Material *material) void Kart::handleMaterialSFX()
{ {
// If a terrain specific sfx is already being played, when a new // If a terrain specific sfx is already being played, when a new
// terrain is entered, an old sfx should be finished (once, not // terrain is entered, an old sfx should be finished (once, not
@ -1790,7 +1791,14 @@ void Kart::handleMaterialSFX(const Material *material)
// FIXME: if there are already two sfx playing, don't add another // FIXME: if there are already two sfx playing, don't add another
// one. This should reduce the performance impact when driving // one. This should reduce the performance impact when driving
// on the bridge in Cocoa. // on the bridge in Cocoa.
if(getLastMaterial()!=material && !m_previous_terrain_sound) const Material *material = m_terrain_info->getMaterial();
// We can not use getLastMaterial() since, since the last material might
// be updated several times during the physics updates, not indicating
// that we have reached a new material with regards to the sound effect.
// So we separately save the material last used for a sound effect and
// then use this for comparison.
if(m_last_sound_material!=material)
{ {
// First stop any previously playing terrain sound // First stop any previously playing terrain sound
// and remove it, so that m_previous_terrain_sound // and remove it, so that m_previous_terrain_sound
@ -1799,19 +1807,21 @@ void Kart::handleMaterialSFX(const Material *material)
{ {
m_previous_terrain_sound->deleteSFX(); m_previous_terrain_sound->deleteSFX();
} }
m_previous_terrain_sound = m_terrain_sound;
if(m_previous_terrain_sound)
m_previous_terrain_sound->setLoop(false);
const std::string &s = material->getSFXName(); // Disable looping for the current terrain sound, and
// make it the previous terrain sound.
if (m_terrain_sound) m_terrain_sound->setLoop(false);
m_previous_terrain_sound = m_terrain_sound;
const std::string &sound_name = material ? material->getSFXName() : "";
// In multiplayer mode sounds are NOT positional, because we have // In multiplayer mode sounds are NOT positional, because we have
// multiple listeners. This would make the sounds of all AIs be // multiple listeners. This would make the sounds of all AIs be
// audible at all times. So silence AI karts. // audible at all times. So silence AI karts.
if (s.size()!=0 && (race_manager->getNumPlayers()==1 || if (!sound_name.empty() && (race_manager->getNumPlayers()==1 ||
m_controller->isLocalPlayerController() ) ) m_controller->isLocalPlayerController() ) )
{ {
m_terrain_sound = SFXManager::get()->createSoundSource(s); m_terrain_sound = SFXManager::get()->createSoundSource(sound_name);
m_terrain_sound->play(); m_terrain_sound->play();
m_terrain_sound->setLoop(true); m_terrain_sound->setLoop(true);
} }
@ -1821,6 +1831,8 @@ void Kart::handleMaterialSFX(const Material *material)
} }
} }
// Check if a previous terrain sound (now not looped anymore)
// is finished and can be deleted.
if(m_previous_terrain_sound && if(m_previous_terrain_sound &&
m_previous_terrain_sound->getStatus()==SFXBase::SFX_STOPPED) m_previous_terrain_sound->getStatus()==SFXBase::SFX_STOPPED)
{ {
@ -1837,14 +1849,16 @@ void Kart::handleMaterialSFX(const Material *material)
// terrain sound is not necessarily a looping sound so check its status before // terrain sound is not necessarily a looping sound so check its status before
// setting its speed, to avoid 'ressuscitating' sounds that had already stopped // setting its speed, to avoid 'ressuscitating' sounds that had already stopped
if(m_terrain_sound && main_loop->isLastSubstep() && if(m_terrain_sound &&
(m_terrain_sound->getStatus()==SFXBase::SFX_PLAYING || (m_terrain_sound->getStatus()==SFXBase::SFX_PLAYING ||
m_terrain_sound->getStatus()==SFXBase::SFX_PAUSED)) m_terrain_sound->getStatus()==SFXBase::SFX_PAUSED) )
{ {
m_terrain_sound->setPosition(getXYZ()); m_terrain_sound->setPosition(getXYZ());
material->setSFXSpeed(m_terrain_sound, m_speed, m_schedule_pause); if(material)
material->setSFXSpeed(m_terrain_sound, m_speed, m_schedule_pause);
} }
m_last_sound_material = material;
} // handleMaterialSFX } // handleMaterialSFX
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -3038,7 +3052,7 @@ void Kart::updateGraphics(float dt)
handleMaterialGFX(dt); handleMaterialGFX(dt);
updateEngineSFX(dt); updateEngineSFX(dt);
handleMaterialSFX();
} // updateGraphics } // updateGraphics
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -226,7 +226,12 @@ protected:
static const int EMITTER_COUNT = 3; static const int EMITTER_COUNT = 3;
SFXBase *m_emitters[EMITTER_COUNT]; SFXBase *m_emitters[EMITTER_COUNT];
SFXBase *m_engine_sound; SFXBase *m_engine_sound;
/** Sound to be played depending on terrain. */
SFXBase *m_terrain_sound; SFXBase *m_terrain_sound;
/** The material for which the last sound effect was played. */
const Material *m_last_sound_material;
SFXBase *m_nitro_sound; SFXBase *m_nitro_sound;
/** A pointer to the previous terrain sound needs to be saved so that an /** A pointer to the previous terrain sound needs to be saved so that an
* 'older' sfx can be finished and an abrupt end of the sfx is avoided. */ * 'older' sfx can be finished and an abrupt end of the sfx is avoided. */
@ -244,7 +249,7 @@ protected:
int m_min_nitro_ticks; int m_min_nitro_ticks;
void updatePhysics(int ticks); void updatePhysics(int ticks);
void handleMaterialSFX(const Material *material); void handleMaterialSFX();
void handleMaterialGFX(float dt); void handleMaterialGFX(float dt);
void updateFlying(); void updateFlying();
void updateSliding(); void updateSliding();

View File

@ -54,10 +54,6 @@ public:
/** Returns true if STK is to be stoppe. */ /** Returns true if STK is to be stoppe. */
bool isAborted() const { return m_abort; } bool isAborted() const { return m_abort; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns if this is the last substep. Used to reduce the amount
* of updates (e.g. to sfx position) to once per rendered frame. */
bool isLastSubstep() const { return m_is_last_substep; }
// ------------------------------------------------------------------------
void setFrameBeforeLoadingWorld() { m_frame_before_loading_world = true; } void setFrameBeforeLoadingWorld() { m_frame_before_loading_world = true; }
}; // MainLoop }; // MainLoop