Merge branch 'master' of github.com:supertuxkart/stk-code

This commit is contained in:
hiker 2014-10-16 09:12:19 +11:00
commit 1f87dbb94e
28 changed files with 499 additions and 318 deletions

View File

@ -23,7 +23,6 @@
#include "audio/sfx_base.hpp" #include "audio/sfx_base.hpp"
/** /**
* \brief Dummy sound when ogg or openal aren't available * \brief Dummy sound when ogg or openal aren't available
* \ingroup audio * \ingroup audio
@ -37,24 +36,27 @@ public:
/** Late creation, if SFX was initially disabled */ /** Late creation, if SFX was initially disabled */
virtual bool init() { return true; } virtual bool init() { return true; }
virtual void position(const Vec3 &position) {} virtual void setLoop(bool status) {}
virtual void setLoop(bool status) {} virtual void setPosition(const Vec3 &p) {}
virtual void play() {} virtual void reallySetPosition(const Vec3 &p) {}
virtual void reallyPlayNow() {} virtual void play() {}
virtual void stop() {} virtual void reallyPlayNow() {}
virtual void reallyStopNow() {} virtual void stop() {}
virtual void pause() {} virtual void reallyStopNow() {}
virtual void reallyPauseNow() {} virtual void pause() {}
virtual void resume() {} virtual void reallyPauseNow() {}
virtual void reallyResumeNow() {} virtual void resume() {}
virtual void deleteSFX() { delete this; } virtual void reallyResumeNow() {}
virtual void speed(float factor) {} virtual void deleteSFX() { delete this; }
virtual void volume(float gain) {} virtual void setSpeed(float factor) {}
virtual SFXManager::SFXStatus getStatus() { return SFXManager::SFX_STOPPED; } virtual void reallySetSpeed(float factor) {}
virtual void onSoundEnabledBack() {} virtual void setVolume(float gain) {}
virtual void setRolloff(float rolloff) {} virtual void reallySetVolume(float gain) {}
virtual bool isPlaying() { return false; } virtual SFXStatus getStatus() { return SFX_STOPPED; }
virtual const SFXBuffer* getBuffer() const { return NULL; } virtual void onSoundEnabledBack() {}
virtual void setRolloff(float rolloff) {}
virtual bool isPlaying() { return false; }
virtual const SFXBuffer* getBuffer() const { return NULL; }
}; // DummySFX }; // DummySFX

View File

@ -42,31 +42,41 @@ class Vec3;
class SFXBase : public NoCopy class SFXBase : public NoCopy
{ {
public: public:
/** Status of a sound effect. */
enum SFXStatus
{
SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2,
SFX_INITIAL = 3
};
virtual ~SFXBase() {} virtual ~SFXBase() {}
/** Late creation, if SFX was initially disabled */ /** Late creation, if SFX was initially disabled */
virtual bool init() = 0; virtual bool init() = 0;
virtual void position(const Vec3 &position) = 0; virtual void setPosition(const Vec3 &p) = 0;
virtual void setLoop(bool status) = 0; virtual void reallySetPosition(const Vec3 &p) = 0;
virtual bool isPlaying() = 0; virtual void setLoop(bool status) = 0;
virtual void play() = 0; virtual bool isPlaying() = 0;
virtual void reallyPlayNow() = 0; virtual void play() = 0;
virtual void stop() = 0; virtual void reallyPlayNow() = 0;
virtual void reallyStopNow() = 0; virtual void stop() = 0;
virtual void pause() = 0; virtual void reallyStopNow() = 0;
virtual void reallyPauseNow() = 0; virtual void pause() = 0;
virtual void resume() = 0; virtual void reallyPauseNow() = 0;
virtual void reallyResumeNow() = 0; virtual void resume() = 0;
virtual void deleteSFX() = 0; virtual void reallyResumeNow() = 0;
virtual void speed(float factor) = 0; virtual void deleteSFX() = 0;
virtual void volume(float gain) = 0; virtual void setSpeed(float factor) = 0;
virtual void setMasterVolume(float gain) = 0; virtual void reallySetSpeed(float factor) = 0;
virtual void onSoundEnabledBack() = 0; virtual void setVolume(float gain) = 0;
virtual void setRolloff(float rolloff) = 0; virtual void reallySetVolume(float gain) = 0;
virtual const SFXBuffer* getBuffer() const = 0; virtual void setMasterVolume(float gain) = 0;
virtual SFXManager::SFXStatus getStatus() = 0; virtual void onSoundEnabledBack() = 0;
virtual void setRolloff(float rolloff) = 0;
virtual const SFXBuffer* getBuffer() const = 0;
virtual SFXStatus getStatus() = 0;
}; // SfxBase }; // SFXBase
#endif // HEADER_SFX_HPP #endif // HEADER_SFX_HPP

View File

@ -74,7 +74,10 @@ SFXManager::SFXManager()
m_initialized = music_manager->initialized(); m_initialized = music_manager->initialized();
m_master_gain = UserConfigParams::m_sfx_volume; m_master_gain = UserConfigParams::m_sfx_volume;
// Init position, since it can be used before positionListener is called. // Init position, since it can be used before positionListener is called.
m_position = Vec3(0,0,0); // No need to use lock here, since the thread will be created later.
m_listener_position.getData() = Vec3(0, 0, 0);
m_listener_front = Vec3(0, 0, 1);
m_listener_up = Vec3(0, 1, 0);
loadSfx(); loadSfx();
@ -160,22 +163,69 @@ SFXManager::~SFXManager()
} // ~SFXManager } // ~SFXManager
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** Adds a sound effect to the queue of sfx to be started by the sfx manager. /** Adds a sound effect command to the queue of the sfx manager. Openal
* Starting a sfx can sometimes cause a 5ms delay, so it is done in a * commands can sometimes cause a 5ms delay, so it is done in a separate
* separate thread. * thread.
* \param command The command to execute.
* \param sfx The sound effect to be started. * \param sfx The sound effect to be started.
*/ */
void SFXManager::queue(SFXCommands command, SFXBase *sfx) void SFXManager::queue(SFXCommands command, SFXBase *sfx)
{ {
SFXCommand *sfx_command = new SFXCommand(command, sfx); SFXCommand *sfx_command = new SFXCommand(command, sfx);
queueCommand(sfx_command);
} // queue
//----------------------------------------------------------------------------
/** Adds a sound effect command with a single floating point parameter to the
* queue of the sfx manager. Openal commands can sometimes cause a 5ms delay,
* so it is done in a separate thread.
* \param command The command to execute.
* \param sfx The sound effect to be started.
* \param f Floating point parameter for the command.
*/
void SFXManager::queue(SFXCommands command, SFXBase *sfx, float f)
{
SFXCommand *sfx_command = new SFXCommand(command, sfx, f);
queueCommand(sfx_command);
} // queue(float)
//----------------------------------------------------------------------------
/** Adds a sound effect command with a Vec3 parameter to the queue of the sfx
* manager. Openal commands can sometimes cause a 5ms delay, so it is done in
* a separate thread.
* \param command The command to execute.
* \param sfx The sound effect to be started.
* \param p A Vec3 parameter for the command.
*/
void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p)
{
SFXCommand *sfx_command = new SFXCommand(command, sfx, p);
queueCommand(sfx_command);
} // queue (Vec3)
//----------------------------------------------------------------------------
/** Enqueues a command to the sfx queue threadsafe. Then signal the
* sfx manager to wake up.
* \param command Pointer to the command to queue up.
*/
void SFXManager::queueCommand(SFXCommand *command)
{
m_sfx_commands.lock(); m_sfx_commands.lock();
m_sfx_commands.getData().push_back(sfx_command); m_sfx_commands.getData().push_back(command);
m_sfx_commands.unlock(); m_sfx_commands.unlock();
// Wake up the sfx thread // Wake up the sfx thread
pthread_cond_signal(&m_cond_request); } // queueCommand
} // queue //----------------------------------------------------------------------------
/** Make sures that the sfx thread is started at least one per frame. It also
* adds an update command for the music manager.
* \param dt Time step size.
*/
void SFXManager::update(float dt)
{
queue(SFX_UPDATE_MUSIC, NULL, dt);
pthread_cond_signal(&m_cond_request);
} // update
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** Puts a NULL request into the queue, which will trigger the thread to /** Puts a NULL request into the queue, which will trigger the thread to
@ -224,15 +274,23 @@ void* SFXManager::mainLoop(void *obj)
me->m_sfx_commands.unlock(); me->m_sfx_commands.unlock();
switch(current->m_command) switch(current->m_command)
{ {
case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; case SFX_PLAY: current->m_sfx->reallyPlayNow(); break;
case SFX_STOP: current->m_sfx->reallyStopNow(); break; case SFX_STOP: current->m_sfx->reallyStopNow(); break;
case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break;
case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; case SFX_RESUME: current->m_sfx->reallyResumeNow(); break;
case SFX_DELETE: { case SFX_SPEED: current->m_sfx->reallySetSpeed(
current->m_sfx->reallyStopNow(); current->m_parameter.getX()); break;
me->deleteSFX(current->m_sfx); case SFX_POSITION: current->m_sfx->reallySetPosition(
break; current->m_parameter); break;
} case SFX_VOLUME: current->m_sfx->reallySetVolume(
current->m_parameter.getX()); break;
case SFX_DELETE: {
current->m_sfx->reallyStopNow();
me->deleteSFX(current->m_sfx); break;
}
case SFX_LISTENER: me->reallyPositionListenerNow(); break;
case SFX_UPDATE_MUSIC: music_manager->update(
current->m_parameter.getX()); break;
default: assert("Not yet supported."); default: assert("Not yet supported.");
} }
delete current; delete current;
@ -280,7 +338,7 @@ void SFXManager::soundToggled(const bool on)
{ {
pauseAll(); pauseAll();
} }
} } // soundToggled
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** Returns if sfx can be played. This means sfx are enabled and /** Returns if sfx can be played. This means sfx are enabled and
@ -576,9 +634,7 @@ void SFXManager::resumeAll()
for (std::vector<SFXBase*>::iterator i =m_all_sfx.getData().begin(); for (std::vector<SFXBase*>::iterator i =m_all_sfx.getData().begin();
i!=m_all_sfx.getData().end(); i++) i!=m_all_sfx.getData().end(); i++)
{ {
SFXStatus status = (*i)->getStatus(); (*i)->resume();
// Initial happens when
if (status==SFX_PAUSED) (*i)->resume();
} // for i in m_all_sfx } // for i in m_all_sfx
m_all_sfx.unlock(); m_all_sfx.unlock();
} // resumeAll } // resumeAll
@ -587,6 +643,7 @@ void SFXManager::resumeAll()
/** Returns whether or not an openal error has occurred. If so, an error /** Returns whether or not an openal error has occurred. If so, an error
* message is printed containing the given context. * message is printed containing the given context.
* \param context Context to specify in the error message. * \param context Context to specify in the error message.
* \return True if no error happened.
*/ */
bool SFXManager::checkError(const std::string &context) bool SFXManager::checkError(const std::string &context)
{ {
@ -660,28 +717,51 @@ const std::string SFXManager::getErrorString(int err)
/** Sets the position and orientation of the listener. /** Sets the position and orientation of the listener.
* \param position Position of the listener. * \param position Position of the listener.
* \param front Which way the listener is facing. * \param front Which way the listener is facing.
* \param up The up direction of the listener.
*/ */
void SFXManager::positionListener(const Vec3 &position, const Vec3 &front) void SFXManager::positionListener(const Vec3 &position, const Vec3 &front,
const Vec3 &up)
{
m_listener_position.lock();
m_listener_position.getData() = position;
m_listener_front = front;
m_listener_up = up;
m_listener_position.unlock();
queue(SFX_LISTENER, NULL);
} // positionListener
//-----------------------------------------------------------------------------
/** Sets the position and orientation of the listener.
* \param position Position of the listener.
* \param front Which way the listener is facing.
*/
void SFXManager::reallyPositionListenerNow()
{ {
#if HAVE_OGGVORBIS #if HAVE_OGGVORBIS
if (!UserConfigParams::m_sfx || !m_initialized) return; if (!UserConfigParams::m_sfx || !m_initialized) return;
m_position = position; m_listener_position.lock();
{
//forward vector //forward vector
m_listenerVec[0] = front.getX(); float orientation[6];
m_listenerVec[1] = front.getY(); orientation[0] = m_listener_front.getX();
m_listenerVec[2] = front.getZ(); orientation[1] = m_listener_front.getY();
orientation[2] = m_listener_front.getZ();
//up vector //up vector
m_listenerVec[3] = 0; orientation[3] = m_listener_up.getX();
m_listenerVec[4] = 0; orientation[4] = m_listener_up.getY();
m_listenerVec[5] = 1; orientation[5] = m_listener_up.getZ();
const Vec3 &pos = m_listener_position.getData();
alListener3f(AL_POSITION, pos.getX(), pos.getY(), pos.getZ());
alListenerfv(AL_ORIENTATION, orientation);
}
m_listener_position.unlock();
alListener3f(AL_POSITION, position.getX(), position.getY(), position.getZ());
alListenerfv(AL_ORIENTATION, m_listenerVec);
#endif #endif
} } // reallyPositionListenerNow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Positional sound is cool, but creating a new object just to play a simple /** Positional sound is cool, but creating a new object just to play a simple

View File

@ -62,12 +62,17 @@ public:
* for each sfx. */ * for each sfx. */
enum SFXCommands enum SFXCommands
{ {
SFX_PLAY = 1, SFX_PLAY = 1,
SFX_STOP = 2, SFX_STOP,
SFX_PAUSE = 3, SFX_PAUSE,
SFX_RESUME = 4, SFX_RESUME,
SFX_DELETE = 5, SFX_DELETE,
SFX_EXIT = 6, SFX_SPEED,
SFX_POSITION,
SFX_VOLUME,
SFX_LISTENER,
SFX_UPDATE_MUSIC,
SFX_EXIT,
}; // SFXCommands }; // SFXCommands
/** /**
@ -89,13 +94,6 @@ public:
NUM_CUSTOMS NUM_CUSTOMS
}; };
/** Status of a sound effect. */
enum SFXStatus
{
SFX_UNKNOWN = -1, SFX_STOPPED = 0, SFX_PAUSED = 1, SFX_PLAYING = 2,
SFX_INITIAL = 3
};
private: private:
/** Data structure for the queue, which stores a sfx and the command to /** Data structure for the queue, which stores a sfx and the command to
@ -105,17 +103,45 @@ private:
private: private:
LEAK_CHECK() LEAK_CHECK()
public: public:
/** The sound effect for which the command should be executed. */
SFXBase *m_sfx; SFXBase *m_sfx;
/** The command to execute. */
SFXCommands m_command; SFXCommands m_command;
/** Optional parameter for commands that need more input. */
Vec3 m_parameter;
// --------------------------------------------------------------------
SFXCommand(SFXCommands command, SFXBase *base) SFXCommand(SFXCommands command, SFXBase *base)
{ {
m_command = command; m_command = command;
m_sfx = base; m_sfx = base;
} } // SFXCommand()
// --------------------------------------------------------------------
SFXCommand(SFXCommands command, SFXBase *base, float parameter)
{
m_command = command;
m_sfx = base;
m_parameter.setX(parameter);
} // SFXCommand(float)
// --------------------------------------------------------------------
SFXCommand(SFXCommands command, SFXBase *base, const Vec3 &parameter)
{
m_command = command;
m_sfx = base;
m_parameter = parameter;
} // SFXCommand(Vec3)
}; // SFXCommand }; // SFXCommand
// ========================================================================
/** The position of the listener. Its lock will be used to
* access m_listener_{position,front, up}. */
Synchronised<Vec3> m_listener_position;
/** The direction the listener is facing. */
Vec3 m_listener_front;
/** Up vector of the listener. */
Vec3 m_listener_up;
/** Listener position */
Vec3 m_position;
/** The buffers and info for all sound effects. These are shared among all /** The buffers and info for all sound effects. These are shared among all
* instances of SFXOpenal. */ * instances of SFXOpenal. */
@ -130,9 +156,6 @@ private:
/** To play non-positional sounds without having to create a new object for each */ /** To play non-positional sounds without having to create a new object for each */
std::map<std::string, SFXBase*> m_quick_sounds; std::map<std::string, SFXBase*> m_quick_sounds;
/** listener vector (position vector + up vector) */
float m_listenerVec[6];
/** If the sfx manager has been initialised. */ /** If the sfx manager has been initialised. */
bool m_initialized; bool m_initialized;
@ -151,10 +174,15 @@ private:
static void* mainLoop(void *obj); static void* mainLoop(void *obj);
void deleteSFX(SFXBase *sfx); void deleteSFX(SFXBase *sfx);
void queueCommand(SFXCommand *command);
void reallyPositionListenerNow();
public: public:
static void create(); static void create();
static void destroy(); static void destroy();
void queue(SFXCommands command, SFXBase *sfx); void queue(SFXCommands command, SFXBase *sfx);
void queue(SFXCommands command, SFXBase *sfx, float f);
void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Static function to get the singleton sfx manager. */ /** Static function to get the singleton sfx manager. */
static SFXManager *get() static SFXManager *get()
@ -186,6 +214,7 @@ public:
void deleteSFXMapping(const std::string &name); void deleteSFXMapping(const std::string &name);
void pauseAll(); void pauseAll();
void resumeAll(); void resumeAll();
void update(float dt);
bool soundExist(const std::string &name); bool soundExist(const std::string &name);
void setMasterSFXVolume(float gain); void setMasterSFXVolume(float gain);
float getMasterSFXVolume() const { return m_master_gain; } float getMasterSFXVolume() const { return m_master_gain; }
@ -193,7 +222,8 @@ public:
static bool checkError(const std::string &context); static bool checkError(const std::string &context);
static const std::string getErrorString(int err); static const std::string getErrorString(int err);
void positionListener(const Vec3 &position, const Vec3 &front); void positionListener(const Vec3 &position,
const Vec3 &front, const Vec3 &up);
SFXBase* quickSound(const std::string &soundName); SFXBase* quickSound(const std::string &soundName);
/** Called when sound was muted/unmuted */ /** Called when sound was muted/unmuted */
@ -206,7 +236,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the current position of the listener. */ /** Returns the current position of the listener. */
Vec3 getListenerPos() const { return m_position; } Vec3 getListenerPos() const { return m_listener_position.getData(); }
}; };

View File

@ -23,8 +23,7 @@
#include "audio/sfx_buffer.hpp" #include "audio/sfx_buffer.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "io/file_manager.hpp" #include "modes/world.hpp"
#include "race/race_manager.hpp"
#include "utils/vs.hpp" #include "utils/vs.hpp"
#ifdef __APPLE__ #ifdef __APPLE__
@ -38,18 +37,19 @@
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBuffer) : SFXBase() SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool owns_buffer) : SFXBase()
{ {
m_soundBuffer = buffer; m_sound_buffer = buffer;
m_soundSource = 0; m_sound_source = 0;
m_ok = false; m_status = SFX_UNKNOWN;
m_is_playing = false; m_is_playing = false;
m_positional = positional; m_positional = positional;
m_defaultGain = gain; m_defaultGain = gain;
m_loop = false; m_loop = false;
m_gain = -1.0f; m_gain = -1.0f;
m_master_gain = 1.0f; m_master_gain = 1.0f;
m_owns_buffer = ownsBuffer; m_owns_buffer = owns_buffer;
m_end_time = -1.0f;
// Don't initialise anything else if the sfx manager was not correctly // Don't initialise anything else if the sfx manager was not correctly
// initialised. First of all the initialisation will not work, and it // initialised. First of all the initialisation will not work, and it
@ -61,18 +61,19 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBu
} // SFXOpenAL } // SFXOpenAL
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Deletes the sfx source, and if it owns the buffer, also deletes the sound
* buffer. */
SFXOpenAL::~SFXOpenAL() SFXOpenAL::~SFXOpenAL()
{ {
if (m_ok) if (m_status!=SFX_UNKNOWN)
{ {
alDeleteSources(1, &m_soundSource); alDeleteSources(1, &m_sound_source);
} }
if (m_owns_buffer && m_soundBuffer != NULL) if (m_owns_buffer && m_sound_buffer)
{ {
m_soundBuffer->unload(); m_sound_buffer->unload();
delete m_soundBuffer; delete m_sound_buffer;
} }
} // ~SFXOpenAL } // ~SFXOpenAL
@ -80,54 +81,78 @@ SFXOpenAL::~SFXOpenAL()
bool SFXOpenAL::init() bool SFXOpenAL::init()
{ {
alGenSources(1, &m_soundSource ); alGenSources(1, &m_sound_source );
if (!SFXManager::checkError("generating a source")) return false; if (!SFXManager::checkError("generating a source")) return false;
assert( alIsBuffer(m_soundBuffer->getBufferID()) ); assert( alIsBuffer(m_sound_buffer->getBufferID()) );
assert( alIsSource(m_soundSource) ); assert( alIsSource(m_sound_source) );
//Log::info("SFXOpenAL", "Setting a source with buffer, %p, rolloff %f, gain = %f, position = %s", alSourcei (m_sound_source, AL_BUFFER, m_sound_buffer->getBufferID());
// m_soundBuffer, rolloff, m_defaultGain, positional ? "true" : "false");
alSourcei (m_soundSource, AL_BUFFER, m_soundBuffer->getBufferID());
if (!SFXManager::checkError("attaching the buffer to the source")) if (!SFXManager::checkError("attaching the buffer to the source"))
return false; return false;
alSource3f(m_soundSource, AL_POSITION, 0.0, 0.0, 0.0); alSource3f(m_sound_source, AL_POSITION, 0.0, 0.0, 0.0);
alSource3f(m_soundSource, AL_VELOCITY, 0.0, 0.0, 0.0); alSource3f(m_sound_source, AL_VELOCITY, 0.0, 0.0, 0.0);
alSource3f(m_soundSource, AL_DIRECTION, 0.0, 0.0, 0.0); alSource3f(m_sound_source, AL_DIRECTION, 0.0, 0.0, 0.0);
alSourcef (m_soundSource, AL_ROLLOFF_FACTOR, m_soundBuffer->getRolloff()); alSourcef (m_sound_source, AL_ROLLOFF_FACTOR, m_sound_buffer->getRolloff());
alSourcef (m_soundSource, AL_MAX_DISTANCE, m_soundBuffer->getMaxDist()); alSourcef (m_sound_source, AL_MAX_DISTANCE, m_sound_buffer->getMaxDist());
if (m_gain < 0.0f) if (m_gain < 0.0f)
{ {
alSourcef (m_soundSource, AL_GAIN, m_defaultGain * m_master_gain); alSourcef (m_sound_source, AL_GAIN, m_defaultGain * m_master_gain);
} }
else else
{ {
alSourcef (m_soundSource, AL_GAIN, m_gain * m_master_gain); alSourcef (m_sound_source, AL_GAIN, m_gain * m_master_gain);
} }
if (m_positional) alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_FALSE); if (m_positional) alSourcei (m_sound_source, AL_SOURCE_RELATIVE, AL_FALSE);
else alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_TRUE); else alSourcei (m_sound_source, AL_SOURCE_RELATIVE, AL_TRUE);
alSourcei(m_soundSource, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE); alSourcei(m_sound_source, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE);
m_ok = SFXManager::checkError("setting up the source"); if(SFXManager::checkError("setting up the source"))
m_status = SFX_INITIAL;
return m_ok; return m_status==SFX_INITIAL;
} // init } // init
// ------------------------------------------------------------------------
/** Returns the status of this sfx. */
SFXBase::SFXStatus SFXOpenAL::getStatus()
{
if(m_status==SFX_PLAYING)
{
if(m_loop) return SFX_PLAYING;
if(World::getWorld() && World::getWorld()->getTime() > m_end_time)
{
m_status = SFX_STOPPED;
return m_status;
}
}
return m_status;
} // getStatus;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Changes the pitch of a sound effect. /** Queues up a change of the pitch of a sound effect to the sfx manager.
* \param factor Speedup/slowdown between 0.5 and 2.0 * \param factor Speedup/slowdown between 0.5 and 2.0
*/ */
void SFXOpenAL::speed(float factor) void SFXOpenAL::setSpeed(float factor)
{ {
if(!m_ok || isnan(factor)) return; if(m_status==SFX_UNKNOWN) return;
assert(!isnan(factor));
SFXManager::get()->queue(SFXManager::SFX_SPEED, this, factor);
} // setSpeed
//-----------------------------------------------------------------------------
/** Changes the pitch of a sound effect. Executed from the sfx manager thread.
* \param factor Speedup/slowdown between 0.5 and 2.0
*/
void SFXOpenAL::reallySetSpeed(float factor)
{
if(m_status==SFX_UNKNOWN) return;
//OpenAL only accepts pitches in the range of 0.5 to 2.0 //OpenAL only accepts pitches in the range of 0.5 to 2.0
if(factor > 2.0f) if(factor > 2.0f)
{ {
@ -137,23 +162,33 @@ void SFXOpenAL::speed(float factor)
{ {
factor = 0.5f; factor = 0.5f;
} }
alSourcef(m_soundSource,AL_PITCH,factor); alSourcef(m_sound_source,AL_PITCH,factor);
SFXManager::checkError("changing the speed"); } // reallySetSpeed
} // speed
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Changes the volume of a sound effect. /** Changes the volume of a sound effect.
* \param gain Volume adjustment between 0.0 (mute) and 1.0 (full volume). * \param gain Volume adjustment between 0.0 (mute) and 1.0 (full volume).
*/ */
void SFXOpenAL::volume(float gain) void SFXOpenAL::setVolume(float gain)
{ {
if(m_status==SFX_UNKNOWN) return;
assert(!isnan(gain)) ;
SFXManager::get()->queue(SFXManager::SFX_VOLUME, this, gain);
} // setVolume
//-----------------------------------------------------------------------------
/** Changes the volume of a sound effect.
* \param gain Volume adjustment between 0.0 (mute) and 1.0 (full volume).
*/
void SFXOpenAL::reallySetVolume(float gain)
{
if(m_status==SFX_UNKNOWN) return;
m_gain = m_defaultGain * gain; m_gain = m_defaultGain * gain;
if(!m_ok) return; if(m_status==SFX_UNKNOWN) return;
alSourcef(m_soundSource, AL_GAIN, m_gain * m_master_gain); alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain);
SFXManager::checkError("setting volume"); } // reallySetVolume
} // volume
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -161,9 +196,9 @@ void SFXOpenAL::setMasterVolume(float gain)
{ {
m_master_gain = gain; m_master_gain = gain;
if(!m_ok) return; if(m_status==SFX_UNKNOWN) return;
alSourcef(m_soundSource, AL_GAIN, alSourcef(m_sound_source, AL_GAIN,
(m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
SFXManager::checkError("setting volume"); SFXManager::checkError("setting volume");
} //setMasterVolume } //setMasterVolume
@ -175,9 +210,9 @@ void SFXOpenAL::setLoop(bool status)
{ {
m_loop = status; m_loop = status;
if(!m_ok) return; if(m_status==SFX_UNKNOWN) return;
alSourcei(m_soundSource, AL_LOOPING, status ? AL_TRUE : AL_FALSE); alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE);
SFXManager::checkError("looping"); SFXManager::checkError("looping");
} // loop } // loop
@ -188,17 +223,19 @@ void SFXOpenAL::stop()
{ {
SFXManager::get()->queue(SFXManager::SFX_STOP, this); SFXManager::get()->queue(SFXManager::SFX_STOP, this);
} // stop } // stop
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** The sfx manager thread executes a stop for this sfx. /** The sfx manager thread executes a stop for this sfx.
*/ */
void SFXOpenAL::reallyStopNow() void SFXOpenAL::reallyStopNow()
{ {
if(!m_ok) return; if(m_status==SFX_UNKNOWN) return;
m_is_playing = false; m_is_playing = false;
m_status = SFX_STOPPED;
m_loop = false; m_loop = false;
alSourcei(m_soundSource, AL_LOOPING, AL_FALSE); alSourcei(m_sound_source, AL_LOOPING, AL_FALSE);
alSourceStop(m_soundSource); alSourceStop(m_sound_source);
SFXManager::checkError("stoping"); SFXManager::checkError("stoping");
} // reallyStopNow } // reallyStopNow
@ -216,8 +253,13 @@ void SFXOpenAL::pause()
*/ */
void SFXOpenAL::reallyPauseNow() void SFXOpenAL::reallyPauseNow()
{ {
if(!m_ok) return; // This updates the status, i.e. potentially switches from
alSourcePause(m_soundSource); // playing to stopped.
getStatus();
if(m_status!=SFX_PLAYING) return;
m_status = SFX_PAUSED;
alSourcePause(m_sound_source);
SFXManager::checkError("pausing"); SFXManager::checkError("pausing");
} // reallyPauseNow } // reallyPauseNow
@ -234,17 +276,14 @@ void SFXOpenAL::resume()
*/ */
void SFXOpenAL::reallyResumeNow() void SFXOpenAL::reallyResumeNow()
{ {
if (!m_ok) // Will init the sfx (lazy) if necessary.
getStatus();
if(m_status==SFX_PAUSED)
{ {
// lazily create OpenAL source when needed alSourcePlay(m_sound_source);
init(); SFXManager::checkError("resuming");
m_status = SFX_PLAYING;
// creation of OpenAL source failed, giving up
if (!m_ok) return;
} }
alSourcePlay(m_soundSource);
SFXManager::checkError("resuming");
} // reallyResumeNow } // reallyResumeNow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -276,17 +315,24 @@ void SFXOpenAL::play()
void SFXOpenAL::reallyPlayNow() void SFXOpenAL::reallyPlayNow()
{ {
if (!SFXManager::get()->sfxAllowed()) return; if (!SFXManager::get()->sfxAllowed()) return;
if (!m_ok) if (m_status==SFX_UNKNOWN)
{ {
// lazily create OpenAL source when needed // lazily create OpenAL source when needed
init(); init();
// creation of OpenAL source failed, giving up // creation of OpenAL source failed, giving up
if (!m_ok) return; if (m_status==SFX_UNKNOWN) return;
} }
alSourcePlay(m_soundSource); alSourcePlay(m_sound_source);
m_status = SFX_PLAYING;
SFXManager::checkError("playing"); SFXManager::checkError("playing");
// At non-race time the end time is not important
if(World::getWorld())
m_end_time = World::getWorld()->getTime()+m_sound_buffer->getDuration();
else
m_end_time = 1.0f;
} // reallyPlayNow } // reallyPlayNow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -301,13 +347,25 @@ bool SFXOpenAL::isPlaying()
/** Sets the position where this sound effects is played. /** Sets the position where this sound effects is played.
* \param position Position of the sound effect. * \param position Position of the sound effect.
*/ */
void SFXOpenAL::position(const Vec3 &position) void SFXOpenAL::setPosition(const Vec3 &position)
{
if (m_status == SFX_UNKNOWN) return;
SFXManager::get()->queue(SFXManager::SFX_POSITION, this, position);
} // setPosition
//-----------------------------------------------------------------------------
/** Sets the position where this sound effects is played.
* \param position Position of the sound effect.
*/
void SFXOpenAL::reallySetPosition(const Vec3 &position)
{ {
if(!UserConfigParams::m_sfx) if(!UserConfigParams::m_sfx)
return; return;
if (!m_ok) if (m_status==SFX_UNKNOWN)
{ {
Log::warn("SFX", "Position called on non-ok SFX <%s>", m_soundBuffer->getFileName().c_str()); Log::warn("SFX", "Position called on non-ok SFX <%s>",
m_sound_buffer->getFileName().c_str());
return; return;
} }
if (!m_positional) if (!m_positional)
@ -322,39 +380,20 @@ void SFXOpenAL::position(const Vec3 &position)
return; return;
} }
alSource3f(m_soundSource, AL_POSITION, alSource3f(m_sound_source, AL_POSITION,
(float)position.getX(), (float)position.getY(), (float)position.getZ()); (float)position.getX(), (float)position.getY(), (float)position.getZ());
if (SFXManager::get()->getListenerPos().distance(position) > m_soundBuffer->getMaxDist()) if (SFXManager::get()->getListenerPos().distance(position) > m_sound_buffer->getMaxDist())
{ {
alSourcef(m_soundSource, AL_GAIN, 0); alSourcef(m_sound_source, AL_GAIN, 0);
} }
else else
{ {
alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
} }
SFXManager::checkError("positioning"); SFXManager::checkError("positioning");
} // position } // reallySetPosition
//-----------------------------------------------------------------------------
/** Returns the status of this sound effect.
*/
SFXManager::SFXStatus SFXOpenAL::getStatus()
{
if(!m_ok) return SFXManager::SFX_UNKNOWN;
int state = 0;
alGetSourcei(m_soundSource, AL_SOURCE_STATE, &state);
switch(state)
{
case AL_STOPPED: return SFXManager::SFX_STOPPED;
case AL_PLAYING: return SFXManager::SFX_PLAYING;
case AL_PAUSED: return SFXManager::SFX_PAUSED;
case AL_INITIAL: return SFXManager::SFX_INITIAL;
default: return SFXManager::SFX_UNKNOWN;
}
} // getStatus
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -362,22 +401,22 @@ void SFXOpenAL::onSoundEnabledBack()
{ {
if (m_loop) if (m_loop)
{ {
if (!m_ok) init(); if (m_status==SFX_UNKNOWN) init();
if (m_ok) if (m_status!=SFX_UNKNOWN)
{ {
alSourcef(m_soundSource, AL_GAIN, 0); alSourcef(m_sound_source, AL_GAIN, 0);
play(); play();
pause(); pause();
alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
} }
} }
} } // onSoundEnabledBack
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SFXOpenAL::setRolloff(float rolloff) void SFXOpenAL::setRolloff(float rolloff)
{ {
alSourcef (m_soundSource, AL_ROLLOFF_FACTOR, rolloff); alSourcef (m_sound_source, AL_ROLLOFF_FACTOR, rolloff);
} }
#endif //if HAVE_OGGVORBIS #endif //if HAVE_OGGVORBIS

View File

@ -28,7 +28,6 @@
# include <AL/al.h> # include <AL/al.h>
#endif #endif
#include "audio/sfx_base.hpp" #include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp"
#include "utils/leak_check.hpp" #include "utils/leak_check.hpp"
/** /**
@ -38,9 +37,17 @@
class SFXOpenAL : public SFXBase class SFXOpenAL : public SFXBase
{ {
private: private:
SFXBuffer* m_soundBuffer; //!< Buffers hold sound data. LEAK_CHECK()
ALuint m_soundSource; //!< Sources are points emitting sound.
bool m_ok; /** Buffers hold sound data. */
SFXBuffer* m_sound_buffer;
/** Sources are points emitting sound. */
ALuint m_sound_source;
/** The status of this SFX. */
SFXStatus m_status;
bool m_positional; bool m_positional;
float m_defaultGain; float m_defaultGain;
@ -62,38 +69,44 @@ private:
/** The master gain set in user preferences */ /** The master gain set in user preferences */
float m_master_gain; float m_master_gain;
/** If this sfx should also free the sound buffer. */
bool m_owns_buffer; bool m_owns_buffer;
/** Time at which a sfx ends playing. Used to avoid frequently getting
* the openl status (which can slow down stk). */
float m_end_time;
public: public:
SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, SFXOpenAL(SFXBuffer* buffer, bool positional, float gain,
bool owns_buffer = false); bool owns_buffer = false);
virtual ~SFXOpenAL(); virtual ~SFXOpenAL();
/** Late creation, if SFX was initially disabled */ virtual bool init();
virtual bool init(); virtual void play();
virtual void reallyPlayNow();
virtual void setLoop(bool status);
virtual bool isPlaying();
virtual void stop();
virtual void reallyStopNow();
virtual void pause();
virtual void reallyPauseNow();
virtual void resume();
virtual void reallyResumeNow();
virtual void deleteSFX();
virtual void setSpeed(float factor);
virtual void reallySetSpeed(float factor);
virtual void setPosition(const Vec3 &position);
virtual void reallySetPosition(const Vec3 &p);
virtual void setVolume(float gain);
virtual void reallySetVolume(float gain);
virtual void setMasterVolume(float gain);
virtual void onSoundEnabledBack();
virtual void setRolloff(float rolloff);
virtual SFXStatus getStatus();
virtual void play(); // ------------------------------------------------------------------------
virtual void reallyPlayNow(); /** Returns the buffer associated with this sfx. */
virtual void setLoop(bool status); virtual const SFXBuffer* getBuffer() const { return m_sound_buffer; }
virtual bool isPlaying();
virtual void stop();
virtual void reallyStopNow();
virtual void pause();
virtual void reallyPauseNow();
virtual void resume();
virtual void reallyResumeNow();
virtual void deleteSFX();
virtual void speed(float factor);
virtual void position(const Vec3 &position);
virtual void volume(float gain);
virtual void setMasterVolume(float gain);
virtual SFXManager::SFXStatus getStatus();
virtual void onSoundEnabledBack();
virtual void setRolloff(float rolloff);
virtual const SFXBuffer* getBuffer() const { return m_soundBuffer; }
LEAK_CHECK()
}; // SFXOpenAL }; // SFXOpenAL

View File

@ -372,7 +372,9 @@ void Camera::smoothMoveCamera(float dt)
if (race_manager->getNumLocalPlayers() < 2) if (race_manager->getNumLocalPlayers() < 2)
{ {
SFXManager::get()->positionListener(current_position, current_target - current_position); SFXManager::get()->positionListener(current_position,
current_target - current_position,
Vec3(0,1,0));
} }
} // smoothMoveCamera } // smoothMoveCamera
@ -578,7 +580,8 @@ void Camera::positionCamera(float dt, float above_kart, float cam_angle,
if (race_manager->getNumLocalPlayers() < 2) if (race_manager->getNumLocalPlayers() < 2)
{ {
SFXManager::get()->positionListener(m_camera->getPosition(), SFXManager::get()->positionListener(m_camera->getPosition(),
wanted_target - m_camera->getPosition()); wanted_target - m_camera->getPosition(),
Vec3(0, 1, 0));
} }
} }

View File

@ -27,13 +27,13 @@ HitSFX::HitSFX(const Vec3& coord, const char* explosion_sound)
: HitEffect() : HitEffect()
{ {
m_sfx = SFXManager::get()->createSoundSource( explosion_sound ); m_sfx = SFXManager::get()->createSoundSource( explosion_sound );
m_sfx->position(coord); m_sfx->setPosition(coord);
// in multiplayer mode, sounds are NOT positional (because we have // in multiplayer mode, sounds are NOT positional (because we have
// multiple listeners) so the sounds of all AIs are constantly heard. // multiple listeners) so the sounds of all AIs are constantly heard.
// Therefore reduce volume of sounds. // Therefore reduce volume of sounds.
float vol = race_manager->getNumLocalPlayers() > 1 ? 0.5f : 1.0f; float vol = race_manager->getNumLocalPlayers() > 1 ? 0.5f : 1.0f;
m_sfx->volume(vol); m_sfx->setVolume(vol);
m_sfx->play(); m_sfx->play();
} // HitSFX } // HitSFX
@ -53,7 +53,7 @@ HitSFX::~HitSFX()
void HitSFX::setPlayerKartHit() void HitSFX::setPlayerKartHit()
{ {
if(race_manager->getNumLocalPlayers()) if(race_manager->getNumLocalPlayers())
m_sfx->volume(1.0f); m_sfx->setVolume(1.0f);
} // setPlayerKartHit } // setPlayerKartHit
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -64,7 +64,7 @@ void HitSFX::setPlayerKartHit()
*/ */
bool HitSFX::updateAndDelete(float dt) bool HitSFX::updateAndDelete(float dt)
{ {
SFXManager::SFXStatus status = m_sfx->getStatus(); SFXBase::SFXStatus status = m_sfx->getStatus();
if(status==SFXManager::SFX_INITIAL) return false; if(status==SFXBase::SFX_INITIAL) return false;
return status!= SFXManager::SFX_PLAYING; return status!= SFXBase::SFX_PLAYING;
} // updateAndDelete } // updateAndDelete

View File

@ -646,14 +646,14 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) con
if (speed < 0) speed = -speed; if (speed < 0) speed = -speed;
// If we paused it due to too low speed earlier, we can continue now. // If we paused it due to too low speed earlier, we can continue now.
if (sfx->getStatus() == SFXManager::SFX_PAUSED) if (sfx->getStatus() == SFXBase::SFX_PAUSED)
{ {
if (speed<m_sfx_min_speed || should_be_paused == 1) return; if (speed<m_sfx_min_speed || should_be_paused == 1) return;
// TODO: Do we first need to stop the sound completely so it // TODO: Do we first need to stop the sound completely so it
// starts over? // starts over?
sfx->play(); sfx->play();
} }
else if (sfx->getStatus() == SFXManager::SFX_PLAYING) else if (sfx->getStatus() == SFXBase::SFX_PLAYING)
{ {
if (speed<m_sfx_min_speed || should_be_paused == 1) if (speed<m_sfx_min_speed || should_be_paused == 1)
{ {
@ -664,12 +664,12 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) con
} }
if (speed > m_sfx_max_speed) if (speed > m_sfx_max_speed)
{ {
sfx->speed(m_sfx_max_pitch); sfx->setSpeed(m_sfx_max_pitch);
return; return;
} }
float f = m_sfx_pitch_per_speed*(speed-m_sfx_min_speed) + m_sfx_min_pitch; float f = m_sfx_pitch_per_speed*(speed-m_sfx_min_speed) + m_sfx_min_pitch;
sfx->speed(f); sfx->setSpeed(f);
} // setSFXSpeed } // setSFXSpeed
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -757,9 +757,9 @@ void DynamicRibbonWidget::onRibbonWidgetFocus(RibbonWidget* emitter, const int p
#pragma mark Setters / Actions #pragma mark Setters / Actions
#endif #endif
void DynamicRibbonWidget::scroll(const int x_delta) void DynamicRibbonWidget::scroll(int x_delta, bool evenIfDeactivated)
{ {
if (m_deactivated) return; if (m_deactivated && !evenIfDeactivated) return;
// Refuse to scroll when everything is visible // Refuse to scroll when everything is visible
if ((int)m_items.size() <= m_row_amount*m_col_amount) return; if ((int)m_items.size() <= m_row_amount*m_col_amount) return;
@ -1081,11 +1081,11 @@ bool DynamicRibbonWidget::setSelection(int item_id, const int playerID,
while (!findItemInRows(name.c_str(), &row, &id)) while (!findItemInRows(name.c_str(), &row, &id))
{ {
// if we get here it means the item is scrolled out. Try to find it. // if we get here it means the item is scrolled out. Try to find it.
scroll(1); scroll(1, evenIfDeactivated);
if (iterations > 50) if (iterations > 50)
{ {
Log::fatal("DynamicRibbonWidget::setSelection", "Cannot find item %d (%s)", item_id, name.c_str()); Log::error("DynamicRibbonWidget::setSelection", "Cannot find item %d (%s)", item_id, name.c_str());
return false; return false;
} }

View File

@ -159,7 +159,7 @@ namespace GUIEngine
void buildInternalStructure(); void buildInternalStructure();
/** Call this to scroll within a scrollable ribbon */ /** Call this to scroll within a scrollable ribbon */
void scroll(const int x_delta); void scroll(int x_delta, bool evenIfDeactivated = false);
/** Used for combo ribbons, to contain the ID of the currently selected item for each player */ /** Used for combo ribbons, to contain the ID of the currently selected item for each player */
int m_selected_item[MAX_PLAYER_COUNT]; int m_selected_item[MAX_PLAYER_COUNT];

View File

@ -142,7 +142,7 @@ void Attachment::set(AttachmentType type, float time,
if (m_bomb_sound) m_bomb_sound->deleteSFX(); if (m_bomb_sound) m_bomb_sound->deleteSFX();
m_bomb_sound = SFXManager::get()->createSoundSource("clock"); m_bomb_sound = SFXManager::get()->createSoundSource("clock");
m_bomb_sound->setLoop(true); m_bomb_sound->setLoop(true);
m_bomb_sound->position(m_kart->getXYZ()); m_bomb_sound->setPosition(m_kart->getXYZ());
m_bomb_sound->play(); m_bomb_sound->play();
break; break;
default: default:
@ -439,7 +439,7 @@ void Attachment::update(float dt)
break; break;
case ATTACH_BOMB: case ATTACH_BOMB:
if (m_bomb_sound) m_bomb_sound->position(m_kart->getXYZ()); if (m_bomb_sound) m_bomb_sound->setPosition(m_kart->getXYZ());
// Mesh animation frames are 1 to 61 frames (60 steps) // Mesh animation frames are 1 to 61 frames (60 steps)
// The idea is change second by second, counterclockwise 60 to 0 secs // The idea is change second by second, counterclockwise 60 to 0 secs
@ -474,7 +474,7 @@ void Attachment::update(float dt)
m_time_left = 0.0f; m_time_left = 0.0f;
if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX(); if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX();
m_bubble_explode_sound = SFXManager::get()->createSoundSource("bubblegum_explode"); m_bubble_explode_sound = SFXManager::get()->createSoundSource("bubblegum_explode");
m_bubble_explode_sound->position(m_kart->getXYZ()); m_bubble_explode_sound->setPosition(m_kart->getXYZ());
m_bubble_explode_sound->play(); m_bubble_explode_sound->play();
// drop a small bubble gum // drop a small bubble gum

View File

@ -172,8 +172,8 @@ bool Bowling::updateAndDelete(float dt)
return true; return true;
} }
if (m_roll_sfx->getStatus()==SFXManager::SFX_PLAYING) if (m_roll_sfx->getStatus()==SFXBase::SFX_PLAYING)
m_roll_sfx->position(getXYZ()); m_roll_sfx->setPosition(getXYZ());
return false; return false;
} // updateAndDelete } // updateAndDelete

View File

@ -140,18 +140,14 @@ Material *Powerup::getIcon() const
// Check if it's one of the types which have a separate // Check if it's one of the types which have a separate
// data file which includes the icon: // data file which includes the icon:
return powerup_manager->getIcon(m_type); return powerup_manager->getIcon(m_type);
} } // getIcon
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Does the sound configuration. /** Does the sound configuration.
*/ */
void Powerup::adjustSound() void Powerup::adjustSound()
{ {
m_sound_use->position(m_owner->getXYZ()); m_sound_use->setPosition(m_owner->getXYZ());
// in multiplayer mode, sounds are NOT positional (because we have multiple listeners) // in multiplayer mode, sounds are NOT positional (because we have multiple listeners)
// so the sounds of all AIs are constantly heard. So reduce volume of sounds. // so the sounds of all AIs are constantly heard. So reduce volume of sounds.
if (race_manager->getNumLocalPlayers() > 1) if (race_manager->getNumLocalPlayers() > 1)
@ -160,14 +156,16 @@ void Powerup::adjustSound()
if (m_owner->getController()->isPlayerController()) if (m_owner->getController()->isPlayerController())
{ {
m_sound_use->volume( 1.0f ); m_sound_use->setVolume( 1.0f );
} }
else else
{ {
m_sound_use->volume( std::min(0.5f, 1.0f / race_manager->getNumberOfKarts()) ); m_sound_use->setVolume(
std::min(0.5f, 1.0f / race_manager->getNumberOfKarts()) );
} }
} }
} } // adjustSound
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Use (fire) this powerup. /** Use (fire) this powerup.
*/ */
@ -205,7 +203,7 @@ void Powerup::use()
case PowerupManager::POWERUP_SWITCH: case PowerupManager::POWERUP_SWITCH:
{ {
ItemManager::get()->switchItems(); ItemManager::get()->switchItems();
m_sound_use->position(m_owner->getXYZ()); m_sound_use->setPosition(m_owner->getXYZ());
m_sound_use->play(); m_sound_use->play();
break; break;
} }
@ -310,9 +308,9 @@ void Powerup::use()
// Meanwhile, don't play it near AI karts since they obviously // Meanwhile, don't play it near AI karts since they obviously
// don't hear anything // don't hear anything
if(kart->getController()->isPlayerController()) if(kart->getController()->isPlayerController())
m_sound_use->position(kart->getXYZ()); m_sound_use->setPosition(kart->getXYZ());
else else
m_sound_use->position(m_owner->getXYZ()); m_sound_use->setPosition(m_owner->getXYZ());
m_sound_use->play(); m_sound_use->play();
break; break;
@ -352,9 +350,9 @@ void Powerup::use()
// Meanwhile, don't play it near AI karts since they obviously // Meanwhile, don't play it near AI karts since they obviously
// don't hear anything // don't hear anything
if(m_owner->getController()->isPlayerController()) if(m_owner->getController()->isPlayerController())
m_sound_use->position(m_owner->getXYZ()); m_sound_use->setPosition(m_owner->getXYZ());
else if(player_kart) else if(player_kart)
m_sound_use->position(player_kart->getXYZ()); m_sound_use->setPosition(player_kart->getXYZ());
m_sound_use->play(); m_sound_use->play();
} }
break; break;

View File

@ -107,7 +107,7 @@ RubberBall::RubberBall(AbstractKart *kart)
*/ */
RubberBall::~RubberBall() RubberBall::~RubberBall()
{ {
if(m_ping_sfx->getStatus()==SFXManager::SFX_PLAYING) if(m_ping_sfx->getStatus()==SFXBase::SFX_PLAYING)
m_ping_sfx->stop(); m_ping_sfx->stop();
m_ping_sfx->deleteSFX(); m_ping_sfx->deleteSFX();
} // ~RubberBall } // ~RubberBall
@ -541,9 +541,9 @@ float RubberBall::updateHeight()
if(m_height_timer>m_interval) if(m_height_timer>m_interval)
{ {
m_height_timer -= m_interval; m_height_timer -= m_interval;
if(m_ping_sfx->getStatus()!=SFXManager::SFX_PLAYING) if(m_ping_sfx->getStatus()!=SFXBase::SFX_PLAYING)
{ {
m_ping_sfx->position(getXYZ()); m_ping_sfx->setPosition(getXYZ());
m_ping_sfx->play(); m_ping_sfx->play();
} }

View File

@ -275,7 +275,7 @@ void Swatter::squashThingsAround()
assert(swatter_node); assert(swatter_node);
Vec3 swatter_pos = swatter_node->getAbsolutePosition(); Vec3 swatter_pos = swatter_node->getAbsolutePosition();
m_swat_sound->position(swatter_pos); m_swat_sound->setPosition(swatter_pos);
m_swat_sound->play(); m_swat_sound->play();
// Squash karts around // Squash karts around

View File

@ -439,7 +439,7 @@ void PlayerController::handleZipper(bool play_sound)
// Only play a zipper sound if it's not already playing, and // Only play a zipper sound if it's not already playing, and
// if the material has changed (to avoid machine gun effect // if the material has changed (to avoid machine gun effect
// on conveyor belt zippers). // on conveyor belt zippers).
if (play_sound || (m_wee_sound->getStatus() != SFXManager::SFX_PLAYING && if (play_sound || (m_wee_sound->getStatus() != SFXBase::SFX_PLAYING &&
m_kart->getMaterial()!=m_kart->getLastMaterial() ) ) m_kart->getMaterial()!=m_kart->getLastMaterial() ) )
{ {
m_wee_sound->play(); m_wee_sound->play();

View File

@ -183,19 +183,19 @@ void Kart::init(RaceManager::KartType type)
{ {
// players have louder sounds than AIs // players have louder sounds than AIs
const float factor = std::min(1.0f, race_manager->getNumLocalPlayers()/2.0f); const float factor = std::min(1.0f, race_manager->getNumLocalPlayers()/2.0f);
m_goo_sound->volume( 1.0f / factor ); m_goo_sound->setVolume( 1.0f / factor );
m_skid_sound->volume( 1.0f / factor ); m_skid_sound->setVolume( 1.0f / factor );
m_crash_sound->volume( 1.0f / factor ); m_crash_sound->setVolume( 1.0f / factor );
m_boing_sound->volume( 1.0f / factor ); m_boing_sound->setVolume( 1.0f / factor );
m_beep_sound->volume( 1.0f / factor ); m_beep_sound->setVolume( 1.0f / factor );
} }
else else
{ {
m_goo_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); m_goo_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
m_skid_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); m_skid_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
m_crash_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); m_crash_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
m_beep_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); m_beep_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
m_boing_sound->volume( 1.0f / race_manager->getNumberOfKarts() ); m_boing_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
} }
} }
@ -756,12 +756,12 @@ void Kart::startEngineSFX()
const float players_volume = (np * 2.0f) / (np*2.0f + np); const float players_volume = (np * 2.0f) / (np*2.0f + np);
if (m_controller->isPlayerController()) if (m_controller->isPlayerController())
m_engine_sound->volume( players_volume / np ); m_engine_sound->setVolume( players_volume / np );
else else
m_engine_sound->volume( (1.0f - players_volume) / nai ); m_engine_sound->setVolume( (1.0f - players_volume) / nai );
} }
m_engine_sound->speed(0.6f); m_engine_sound->setSpeed(0.6f);
m_engine_sound->setLoop(true); m_engine_sound->setLoop(true);
m_engine_sound->play(); m_engine_sound->play();
} // startEngineSFX } // startEngineSFX
@ -928,7 +928,7 @@ void Kart::collectedItem(Item *item, int add_info)
m_kart_properties->getBubblegumSpeedFraction(), m_kart_properties->getBubblegumSpeedFraction(),
m_kart_properties->getBubblegumFadeInTime(), m_kart_properties->getBubblegumFadeInTime(),
m_bubblegum_time); m_bubblegum_time);
m_goo_sound->position(getXYZ()); m_goo_sound->setPosition(getXYZ());
m_goo_sound->play(); m_goo_sound->play();
// Play appropriate custom character sound // Play appropriate custom character sound
playCustomSFX(SFXManager::CUSTOM_GOO); playCustomSFX(SFXManager::CUSTOM_GOO);
@ -1184,11 +1184,11 @@ void Kart::update(float dt)
} }
*/ */
m_beep_sound->position ( getXYZ() ); m_beep_sound->setPosition ( getXYZ() );
m_engine_sound->position ( getXYZ() ); m_engine_sound->setPosition ( getXYZ() );
m_crash_sound->position ( getXYZ() ); m_crash_sound->setPosition ( getXYZ() );
m_skid_sound->position ( getXYZ() ); m_skid_sound->setPosition ( getXYZ() );
m_boing_sound->position ( getXYZ() ); m_boing_sound->setPosition ( getXYZ() );
// Check if a kart is (nearly) upside down and not moving much --> // Check if a kart is (nearly) upside down and not moving much -->
// automatic rescue // automatic rescue
@ -1447,7 +1447,7 @@ void Kart::handleMaterialSFX(const Material *material)
{ {
if (!m_controller->isPlayerController()) if (!m_controller->isPlayerController())
{ {
m_terrain_sound->volume( 0.0f ); m_terrain_sound->setVolume( 0.0f );
} }
} }
@ -1461,7 +1461,7 @@ void Kart::handleMaterialSFX(const Material *material)
} }
if(m_previous_terrain_sound && if(m_previous_terrain_sound &&
m_previous_terrain_sound->getStatus()==SFXManager::SFX_STOPPED) m_previous_terrain_sound->getStatus()==SFXBase::SFX_STOPPED)
{ {
// We don't modify the position of m_previous_terrain_sound // We don't modify the position of m_previous_terrain_sound
// anymore, so that it keeps on playing at the place where the // anymore, so that it keeps on playing at the place where the
@ -1477,10 +1477,10 @@ 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 && if(m_terrain_sound &&
(m_terrain_sound->getStatus()==SFXManager::SFX_PLAYING || (m_terrain_sound->getStatus()==SFXBase::SFX_PLAYING ||
m_terrain_sound->getStatus()==SFXManager::SFX_PAUSED)) m_terrain_sound->getStatus()==SFXBase::SFX_PAUSED))
{ {
m_terrain_sound->position(getXYZ()); m_terrain_sound->setPosition(getXYZ());
material->setSFXSpeed(m_terrain_sound, m_speed, m_schedule_pause); material->setSFXSpeed(m_terrain_sound, m_speed, m_schedule_pause);
} }
@ -1589,7 +1589,7 @@ void Kart::handleMaterialGFX()
const std::string &s = surface_material->getSFXName(); const std::string &s = surface_material->getSFXName();
if (s != "" && !dynamic_cast<RescueAnimation*>(getKartAnimation())&& if (s != "" && !dynamic_cast<RescueAnimation*>(getKartAnimation())&&
(m_terrain_sound == NULL || (m_terrain_sound == NULL ||
m_terrain_sound->getStatus() == SFXManager::SFX_STOPPED)) m_terrain_sound->getStatus() == SFXBase::SFX_STOPPED))
{ {
if (m_previous_terrain_sound) m_previous_terrain_sound->deleteSFX(); if (m_previous_terrain_sound) m_previous_terrain_sound->deleteSFX();
m_previous_terrain_sound = m_terrain_sound; m_previous_terrain_sound = m_terrain_sound;
@ -1892,12 +1892,12 @@ void Kart::crashed(const Material* m, AbstractKart *k)
// it's not already playing. // it's not already playing.
if (isShielded() || (k != NULL && k->isShielded())) if (isShielded() || (k != NULL && k->isShielded()))
{ {
if (m_boing_sound->getStatus() != SFXManager::SFX_PLAYING) if (m_boing_sound->getStatus() != SFXBase::SFX_PLAYING)
m_boing_sound->play(); m_boing_sound->play();
} }
else else
{ {
if(m_crash_sound->getStatus() != SFXManager::SFX_PLAYING) if(m_crash_sound->getStatus() != SFXBase::SFX_PLAYING)
m_crash_sound->play(); m_crash_sound->play();
} }
} }
@ -2123,15 +2123,15 @@ void Kart::updateEngineSFX()
if (f>1.0f) f=1.0f; if (f>1.0f) f=1.0f;
float gears = 3.0f * fmod(f, 0.333334f); float gears = 3.0f * fmod(f, 0.333334f);
m_engine_sound->speed(0.6f + (f +gears)* 0.35f); m_engine_sound->setSpeed(0.6f + (f +gears)* 0.35f);
} }
else else
{ {
// When flying, fixed value but not too high pitch // When flying, fixed value but not too high pitch
// This gives some variation (vs previous "on wheels" one) // This gives some variation (vs previous "on wheels" one)
m_engine_sound->speed(0.9f); m_engine_sound->setSpeed(0.9f);
} }
m_engine_sound->position(getXYZ()); m_engine_sound->setPosition(getXYZ());
} // updateEngineSFX } // updateEngineSFX
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -21,7 +21,7 @@
#include <assert.h> #include <assert.h>
#include "audio/music_manager.hpp" #include "audio/sfx_manager.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
@ -138,7 +138,7 @@ void MainLoop::run()
if (!m_abort && !ProfileWorld::isNoGraphics()) if (!m_abort && !ProfileWorld::isNoGraphics())
{ {
PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00);
music_manager->update(dt); SFXManager::get()->update(dt);
input_manager->update(dt); input_manager->update(dt);
#ifdef ENABLE_WIIUSE #ifdef ENABLE_WIIUSE

View File

@ -309,7 +309,8 @@ void CutsceneWorld::update(float dt)
SFXManager::get()->positionListener(m_camera->getAbsolutePosition(), SFXManager::get()->positionListener(m_camera->getAbsolutePosition(),
m_camera->getTarget() - m_camera->getTarget() -
m_camera->getAbsolutePosition()); m_camera->getAbsolutePosition(),
Vec3(0,1,0));
break; break;
} }

View File

@ -155,7 +155,7 @@ void LinearWorld::update(float dt)
WorldWithRank::update(dt); WorldWithRank::update(dt);
if (m_last_lap_sfx_playing && if (m_last_lap_sfx_playing &&
m_last_lap_sfx->getStatus() != SFXManager::SFX_PLAYING) m_last_lap_sfx->getStatus() != SFXBase::SFX_PLAYING)
{ {
if(music_manager->getCurrentMusic()) if(music_manager->getCurrentMusic())
music_manager->getCurrentMusic()->resetTemporaryVolume(); music_manager->getCurrentMusic()->resetTemporaryVolume();

View File

@ -121,7 +121,7 @@ void SoccerWorld::reset()
} }
if (m_goal_sound != NULL && if (m_goal_sound != NULL &&
m_goal_sound->getStatus() == SFXManager::SFX_PLAYING) m_goal_sound->getStatus() == SFXBase::SFX_PLAYING)
{ {
m_goal_sound->stop(); m_goal_sound->stop();
} }

View File

@ -162,7 +162,7 @@ void WorldStatus::update(const float dt)
// ... phase. Since the sound effect is about 3 seconds // ... phase. Since the sound effect is about 3 seconds
// long, we use the aux timer to force the next phase // long, we use the aux timer to force the next phase
// after 3.5 seconds. // after 3.5 seconds.
if (m_track_intro_sound->getStatus() == SFXManager::SFX_PLAYING && if (m_track_intro_sound->getStatus() == SFXBase::SFX_PLAYING &&
m_auxiliary_timer < 3.5f) m_auxiliary_timer < 3.5f)
return; return;

View File

@ -138,7 +138,7 @@ void OptionsScreenAudio::eventCallback(Widget* widget, const std::string& name,
assert(w != NULL); assert(w != NULL);
if (sample_sound == NULL) sample_sound = SFXManager::get()->createSoundSource( "pre_start_race" ); if (sample_sound == NULL) sample_sound = SFXManager::get()->createSoundSource( "pre_start_race" );
sample_sound->volume(1); sample_sound->setVolume(1);
SFXManager::get()->setMasterSFXVolume( w->getValue()/10.0f ); SFXManager::get()->setMasterSFXVolume( w->getValue()/10.0f );
UserConfigParams::m_sfx_volume = w->getValue()/10.0f; UserConfigParams::m_sfx_volume = w->getValue()/10.0f;

View File

@ -116,7 +116,7 @@ void RaceResultGUI::tearDown()
m_font->setMonospaceDigits(m_was_monospace); m_font->setMonospaceDigits(m_was_monospace);
if (m_finish_sound != NULL && if (m_finish_sound != NULL &&
m_finish_sound->getStatus() == SFXManager::SFX_PLAYING) m_finish_sound->getStatus() == SFXBase::SFX_PLAYING)
{ {
m_finish_sound->stop(); m_finish_sound->stop();
} }
@ -600,7 +600,7 @@ void RaceResultGUI::onUpdate(float dt)
renderGlobal(dt); renderGlobal(dt);
if (m_finish_sound != NULL && if (m_finish_sound != NULL &&
m_finish_sound->getStatus() != SFXManager::SFX_PLAYING) m_finish_sound->getStatus() != SFXBase::SFX_PLAYING)
{ {
try try
{ {

View File

@ -201,7 +201,7 @@ void StateManager::onGameStateChange(GameState new_state)
{ {
irr_driver->showPointer(); irr_driver->showPointer();
input_manager->setMode(InputManager::MENU); input_manager->setMode(InputManager::MENU);
SFXManager::get()->positionListener( Vec3(0,0,0), Vec3(0,1,0) ); SFXManager::get()->positionListener( Vec3(0,0,0), Vec3(0,1,0), Vec3(0, 1, 0) );
if (new_state == MENU) if (new_state == MENU)
{ {

View File

@ -212,11 +212,15 @@ void BaseUserScreen::makeEntryFieldsVisible()
getWidget<LabelWidget>("label_remember")->setVisible(online); getWidget<LabelWidget>("label_remember")->setVisible(online);
getWidget<CheckBoxWidget>("remember-user")->setVisible(online); getWidget<CheckBoxWidget>("remember-user")->setVisible(online);
PlayerProfile *player = getSelectedPlayer(); PlayerProfile *player = getSelectedPlayer();
// Don't show the password fields if the player wants to be online // Don't show the password fields if the player wants to be online
// and either is the current player (no need to enter a password then) // and either is the current player and logged in (no need to enter a
// or has a saved session. // password then) or has a saved session.
if(player && online && if(player && online &&
(player->hasSavedSession() || player==PlayerManager::getCurrentPlayer())) (player->hasSavedSession() ||
(player==PlayerManager::getCurrentPlayer() && player->isLoggedIn() )
)
)
{ {
// If we show the online login fields, but the player has a // If we show the online login fields, but the player has a
// saved session, don't show the password field. // saved session, don't show the password field.
@ -451,6 +455,7 @@ void BaseUserScreen::onUpdate(float dt)
{ {
player->clearSession(); player->clearSession();
makeEntryFieldsVisible(); makeEntryFieldsVisible();
m_username_tb->setText(player->getLastOnlineName());
} }
} }
} // onUpdate } // onUpdate

View File

@ -427,7 +427,7 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_no
m_sound = SFXManager::get()->createSoundSource(buffer, true, true); m_sound = SFXManager::get()->createSoundSource(buffer, true, true);
if (m_sound != NULL) if (m_sound != NULL)
{ {
m_sound->position(m_init_xyz); m_sound->setPosition(m_init_xyz);
if (!trigger_when_near && m_trigger_condition.empty()) if (!trigger_when_near && m_trigger_condition.empty())
{ {
m_sound->setLoop(true); m_sound->setLoop(true);
@ -451,14 +451,14 @@ void TrackObjectPresentationSound::update(float dt)
// muting when too far is implemented manually since not supported by OpenAL // muting when too far is implemented manually since not supported by OpenAL
// so need to call this every frame to update the muting state if listener // so need to call this every frame to update the muting state if listener
// moved // moved
m_sound->position(m_xyz); m_sound->setPosition(m_xyz);
} }
} // update } // update
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void TrackObjectPresentationSound::onTriggerItemApproached(Item* who) void TrackObjectPresentationSound::onTriggerItemApproached(Item* who)
{ {
if (m_sound != NULL && m_sound->getStatus() != SFXManager::SFX_PLAYING) if (m_sound != NULL && m_sound->getStatus() != SFXBase::SFX_PLAYING)
{ {
m_sound->play(); m_sound->play();
} }
@ -495,7 +495,7 @@ void TrackObjectPresentationSound::move(const core::vector3df& xyz,
const core::vector3df& scale) const core::vector3df& scale)
{ {
m_xyz = xyz; m_xyz = xyz;
if (m_sound != NULL) m_sound->position(xyz); if (m_sound != NULL) m_sound->setPosition(xyz);
} // move } // move
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------