Merge branch 'master' of https://github.com/supertuxkart/stk-code
This commit is contained in:
commit
c45f6a1133
@ -23,7 +23,6 @@
|
||||
#include "audio/sfx_base.hpp"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief Dummy sound when ogg or openal aren't available
|
||||
* \ingroup audio
|
||||
@ -37,19 +36,27 @@ public:
|
||||
/** Late creation, if SFX was initially disabled */
|
||||
virtual bool init() { return true; }
|
||||
|
||||
virtual void position(const Vec3 &position) {}
|
||||
virtual void setLoop(bool status) {}
|
||||
virtual void play() {}
|
||||
virtual void stop() {}
|
||||
virtual void pause() {}
|
||||
virtual void resume() {}
|
||||
virtual void speed(float factor) {}
|
||||
virtual void volume(float gain) {}
|
||||
virtual SFXManager::SFXStatus getStatus() { return SFXManager::SFX_STOPPED; }
|
||||
virtual void onSoundEnabledBack() {}
|
||||
virtual void setRolloff(float rolloff) {}
|
||||
virtual bool isPlaying() { return false; }
|
||||
virtual const SFXBuffer* getBuffer() const { return NULL; }
|
||||
virtual void setLoop(bool status) {}
|
||||
virtual void setPosition(const Vec3 &p) {}
|
||||
virtual void reallySetPosition(const Vec3 &p) {}
|
||||
virtual void play() {}
|
||||
virtual void reallyPlayNow() {}
|
||||
virtual void stop() {}
|
||||
virtual void reallyStopNow() {}
|
||||
virtual void pause() {}
|
||||
virtual void reallyPauseNow() {}
|
||||
virtual void resume() {}
|
||||
virtual void reallyResumeNow() {}
|
||||
virtual void deleteSFX() { delete this; }
|
||||
virtual void setSpeed(float factor) {}
|
||||
virtual void reallySetSpeed(float factor) {}
|
||||
virtual void setVolume(float gain) {}
|
||||
virtual void reallySetVolume(float gain) {}
|
||||
virtual SFXStatus getStatus() { return SFX_STOPPED; }
|
||||
virtual void onSoundEnabledBack() {}
|
||||
virtual void setRolloff(float rolloff) {}
|
||||
virtual bool isPlaying() { return false; }
|
||||
virtual const SFXBuffer* getBuffer() const { return NULL; }
|
||||
|
||||
}; // DummySFX
|
||||
|
||||
|
@ -42,27 +42,41 @@ class Vec3;
|
||||
class SFXBase : public NoCopy
|
||||
{
|
||||
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() {}
|
||||
|
||||
/** Late creation, if SFX was initially disabled */
|
||||
virtual bool init() = 0;
|
||||
virtual void position(const Vec3 &position) = 0;
|
||||
virtual void setLoop(bool status) = 0;
|
||||
virtual bool isPlaying() = 0;
|
||||
virtual void play() = 0;
|
||||
virtual void reallyPlayNow() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void pause() = 0;
|
||||
virtual void resume() = 0;
|
||||
virtual void speed(float factor) = 0;
|
||||
virtual void volume(float gain) = 0;
|
||||
virtual void setMasterVolume(float gain) = 0;
|
||||
virtual void onSoundEnabledBack() = 0;
|
||||
virtual void setRolloff(float rolloff) = 0;
|
||||
virtual const SFXBuffer* getBuffer() const = 0;
|
||||
virtual SFXManager::SFXStatus getStatus() = 0;
|
||||
virtual bool init() = 0;
|
||||
virtual void setPosition(const Vec3 &p) = 0;
|
||||
virtual void reallySetPosition(const Vec3 &p) = 0;
|
||||
virtual void setLoop(bool status) = 0;
|
||||
virtual bool isPlaying() = 0;
|
||||
virtual void play() = 0;
|
||||
virtual void reallyPlayNow() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void reallyStopNow() = 0;
|
||||
virtual void pause() = 0;
|
||||
virtual void reallyPauseNow() = 0;
|
||||
virtual void resume() = 0;
|
||||
virtual void reallyResumeNow() = 0;
|
||||
virtual void deleteSFX() = 0;
|
||||
virtual void setSpeed(float factor) = 0;
|
||||
virtual void reallySetSpeed(float factor) = 0;
|
||||
virtual void setVolume(float gain) = 0;
|
||||
virtual void reallySetVolume(float gain) = 0;
|
||||
virtual void setMasterVolume(float gain) = 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
|
||||
|
@ -36,27 +36,37 @@
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/** Creates a sfx. The parameter are taken from the parameters:
|
||||
* \param file File name of the buffer.
|
||||
* \param positional If the sfx is positional.
|
||||
* \param rolloff Rolloff value of this sfx.
|
||||
* \param max_dist Maximum distance the sfx can be heard.
|
||||
* \param gain Gain value of this sfx.
|
||||
*/
|
||||
SFXBuffer::SFXBuffer(const std::string& file,
|
||||
bool positional,
|
||||
float rolloff,
|
||||
float max_width,
|
||||
float max_dist,
|
||||
float gain)
|
||||
{
|
||||
m_buffer = 0;
|
||||
m_gain = 1.0f;
|
||||
m_rolloff = 0.1f;
|
||||
m_loaded = false;
|
||||
m_max_dist = max_width;
|
||||
m_max_dist = max_dist;
|
||||
m_duration = -1.0f;
|
||||
m_file = file;
|
||||
|
||||
m_rolloff = rolloff;
|
||||
m_positional = positional;
|
||||
m_gain = gain;
|
||||
}
|
||||
} // SFXBuffer
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/** Constructor getting the sfx parameters from an XML node.
|
||||
* \param file File name of the data.
|
||||
* \param node XML Node with the data for this sfx.
|
||||
*/
|
||||
SFXBuffer::SFXBuffer(const std::string& file,
|
||||
const XMLNode* node)
|
||||
{
|
||||
@ -64,6 +74,7 @@ SFXBuffer::SFXBuffer(const std::string& file,
|
||||
m_gain = 1.0f;
|
||||
m_rolloff = 0.1f;
|
||||
m_max_dist = 300.0f;
|
||||
m_duration = -1.0f;
|
||||
m_positional = false;
|
||||
m_loaded = false;
|
||||
m_file = file;
|
||||
@ -72,10 +83,15 @@ SFXBuffer::SFXBuffer(const std::string& file,
|
||||
node->get("positional", &m_positional );
|
||||
node->get("volume", &m_gain );
|
||||
node->get("max_dist", &m_max_dist );
|
||||
}
|
||||
node->get("duration", &m_duration );
|
||||
} // SFXBuffer(XMLNode)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/** \brief load the buffer from file into OpenAL.
|
||||
* \note If this buffer is already loaded, this call does nothing and
|
||||
* returns false.
|
||||
* \return Whether loading was successful.
|
||||
*/
|
||||
bool SFXBuffer::load()
|
||||
{
|
||||
if (UserConfigParams::m_sfx == false) return false;
|
||||
@ -103,9 +119,13 @@ bool SFXBuffer::load()
|
||||
|
||||
m_loaded = true;
|
||||
return true;
|
||||
}
|
||||
} // load
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** \brief Frees the loaded buffer.
|
||||
* Cannot appear in destructor because copy-constructors may be used,
|
||||
* and the OpenAL source must not be deleted on a copy
|
||||
*/
|
||||
|
||||
void SFXBuffer::unload()
|
||||
{
|
||||
@ -117,7 +137,7 @@ void SFXBuffer::unload()
|
||||
}
|
||||
#endif
|
||||
m_loaded = false;
|
||||
}
|
||||
} // unload
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** Load a vorbis file into an OpenAL buffer
|
||||
@ -164,7 +184,7 @@ bool SFXBuffer::loadVorbisBuffer(const std::string &name, ALuint buffer)
|
||||
if(!data)
|
||||
{
|
||||
ov_clear(&oggFile);
|
||||
Log::error("SFXBuffer", "[SFXBuffer] loadVorbisBuffer() - Error : LoadVorbisBuffer() - couldn't allocate decode buffer\n");
|
||||
Log::error("SFXBuffer", "[SFXBuffer] Could not allocate decode buffer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -188,9 +208,21 @@ bool SFXBuffer::loadVorbisBuffer(const std::string &name, ALuint buffer)
|
||||
|
||||
ov_clear(&oggFile);
|
||||
fclose(file);
|
||||
|
||||
// Allow the xml data to overwrite the duration, but if there is no
|
||||
// duration (which is the norm), compute it:
|
||||
if(m_duration < 0)
|
||||
{
|
||||
ALint buffer_size, frequency, bits_per_sample, channels;
|
||||
alGetBufferi(buffer, AL_SIZE, &buffer_size );
|
||||
alGetBufferi(buffer, AL_FREQUENCY, &frequency );
|
||||
alGetBufferi(buffer, AL_CHANNELS, &channels );
|
||||
alGetBufferi(buffer, AL_BITS, &bits_per_sample);
|
||||
m_duration = float(buffer_size) / (frequency*channels*(bits_per_sample / 8));
|
||||
}
|
||||
return success;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
} // loadVorbisBuffer
|
||||
|
||||
|
@ -46,18 +46,32 @@ class SFXBuffer
|
||||
{
|
||||
private:
|
||||
|
||||
LEAK_CHECK()
|
||||
|
||||
/** Whether the contents of the file was loaded */
|
||||
bool m_loaded;
|
||||
|
||||
/** The file that contains the OGG audio data */
|
||||
std::string m_file;
|
||||
|
||||
/** The openal buffer id. */
|
||||
ALuint m_buffer;
|
||||
|
||||
/** If the sound is positional. */
|
||||
bool m_positional;
|
||||
|
||||
/** The roll-off value. */
|
||||
float m_rolloff;
|
||||
|
||||
/** The volume gain value. */
|
||||
float m_gain;
|
||||
|
||||
/** Maximum distance the sfx can be heard. */
|
||||
float m_max_dist;
|
||||
|
||||
/** Duration of the sfx. */
|
||||
float m_duration;
|
||||
|
||||
bool loadVorbisBuffer(const std::string &name, ALuint buffer);
|
||||
|
||||
public:
|
||||
@ -70,41 +84,43 @@ public:
|
||||
|
||||
SFXBuffer(const std::string& file,
|
||||
const XMLNode* node);
|
||||
|
||||
~SFXBuffer()
|
||||
{
|
||||
}
|
||||
} // ~SFXBuffer
|
||||
|
||||
/**
|
||||
* \brief load the buffer from file into OpenAL.
|
||||
* \note If this buffer is already loaded, this call does nothing and returns false
|
||||
* \return whether loading was successful
|
||||
*/
|
||||
bool load();
|
||||
|
||||
/**
|
||||
* \brief Frees the loaded buffer
|
||||
* Cannot appear in destructor because copy-constructors may be used,
|
||||
* and the OpenAL source must not be deleted on a copy
|
||||
*/
|
||||
void unload();
|
||||
bool load();
|
||||
void unload();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return whether this buffer was loaded from disk */
|
||||
bool isLoaded() const { return m_loaded; }
|
||||
|
||||
bool isLoaded() const { return m_loaded; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Only returns a valid buffer if isLoaded() returned true */
|
||||
ALuint getBufferID() const { return m_buffer; }
|
||||
ALuint getBufferID() const { return m_buffer; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if the buffer is positional. */
|
||||
bool isPositional() const { return m_positional; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the rolloff value of this buffer. */
|
||||
float getRolloff() const { return m_rolloff; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the gain for this sfx. */
|
||||
float getGain() const { return m_gain; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the maximum distance this sfx can be heard. */
|
||||
float getMaxDist() const { return m_max_dist; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the file name of this buffer. */
|
||||
const std::string& getFileName() const { return m_file; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets if this buffer is positional or not. */
|
||||
void setPositional(bool positional) { m_positional = positional; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long this buffer will play. */
|
||||
float getDuration() const { return m_duration; }
|
||||
|
||||
bool isPositional() const { return m_positional; }
|
||||
float getRolloff() const { return m_rolloff; }
|
||||
float getGain() const { return m_gain; }
|
||||
float getMaxDist() const { return m_max_dist; }
|
||||
std::string getFileName() const { return m_file; }
|
||||
|
||||
void setPositional(bool positional) { m_positional = positional; }
|
||||
|
||||
LEAK_CHECK()
|
||||
};
|
||||
}; // class SFXBuffer
|
||||
|
||||
|
||||
#endif // HEADER_SFX_BUFFER_HPP
|
||||
|
@ -106,9 +106,9 @@ SFXManager::SFXManager()
|
||||
if (!sfxAllowed()) return;
|
||||
|
||||
setMasterSFXVolume( UserConfigParams::m_sfx_volume );
|
||||
m_sfx_to_play.lock();
|
||||
m_sfx_to_play.getData().clear();
|
||||
m_sfx_to_play.unlock();
|
||||
m_sfx_commands.lock();
|
||||
m_sfx_commands.getData().clear();
|
||||
m_sfx_commands.unlock();
|
||||
|
||||
} // SoundManager
|
||||
|
||||
@ -124,13 +124,15 @@ SFXManager::~SFXManager()
|
||||
pthread_cond_destroy(&m_cond_request);
|
||||
|
||||
// ---- clear m_all_sfx
|
||||
const int sfx_amount = (int) m_all_sfx.size();
|
||||
// not strictly necessary, but might avoid copy&paste problems
|
||||
m_all_sfx.lock();
|
||||
const int sfx_amount = (int) m_all_sfx.getData().size();
|
||||
for (int n=0; n<sfx_amount; n++)
|
||||
{
|
||||
delete m_all_sfx[n];
|
||||
delete m_all_sfx.getData()[n];
|
||||
}
|
||||
m_all_sfx.clear();
|
||||
|
||||
m_all_sfx.getData().clear();
|
||||
m_all_sfx.unlock();
|
||||
// ---- clear m_quick_sounds
|
||||
{
|
||||
std::map<std::string, SFXBase*>::iterator i = m_quick_sounds.begin();
|
||||
@ -158,24 +160,59 @@ SFXManager::~SFXManager()
|
||||
} // ~SFXManager
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** Adds a sound effect to the queue of sfx to be started by the sfx manager.
|
||||
* Starting a sfx can sometimes cause a 5ms delay, so it is done in a
|
||||
* separate thread.
|
||||
/** Adds a sound effect command 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.
|
||||
*/
|
||||
void SFXManager::queue(SFXBase *sfx)
|
||||
void SFXManager::queue(SFXCommands command, SFXBase *sfx)
|
||||
{
|
||||
// Don't add sfx that are either not working correctly (e.g. because sfx
|
||||
// are disabled);
|
||||
if(sfx && sfx->getStatus()==SFX_UNKNOWN ) return;
|
||||
SFXCommand *sfx_command = new SFXCommand(command, sfx);
|
||||
queueCommand(sfx_command);
|
||||
} // queue
|
||||
|
||||
m_sfx_to_play.lock();
|
||||
m_sfx_to_play.getData().push_back(sfx);
|
||||
m_sfx_to_play.unlock();
|
||||
//----------------------------------------------------------------------------
|
||||
/** 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.getData().push_back(command);
|
||||
m_sfx_commands.unlock();
|
||||
// Wake up the sfx thread
|
||||
pthread_cond_signal(&m_cond_request);
|
||||
|
||||
} // queue
|
||||
} // queueCommand
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** Puts a NULL request into the queue, which will trigger the thread to
|
||||
@ -183,7 +220,7 @@ void SFXManager::queue(SFXBase *sfx)
|
||||
*/
|
||||
void SFXManager::stopThread()
|
||||
{
|
||||
queue(NULL);
|
||||
queue(SFX_EXIT, NULL);
|
||||
} // stopThread
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -198,40 +235,66 @@ void* SFXManager::mainLoop(void *obj)
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
|
||||
me->m_sfx_to_play.lock();
|
||||
me->m_sfx_commands.lock();
|
||||
|
||||
// Wait till we have an empty sfx in the queue
|
||||
while (me->m_sfx_to_play.getData().empty() ||
|
||||
me->m_sfx_to_play.getData().front()!=NULL )
|
||||
while (me->m_sfx_commands.getData().empty() ||
|
||||
me->m_sfx_commands.getData().front()->m_command!=SFX_EXIT)
|
||||
{
|
||||
bool empty = me->m_sfx_to_play.getData().empty();
|
||||
bool empty = me->m_sfx_commands.getData().empty();
|
||||
|
||||
// Wait in cond_wait for a request to arrive. The 'while' is necessary
|
||||
// since "spurious wakeups from the pthread_cond_wait ... may occur"
|
||||
// (pthread_cond_wait man page)!
|
||||
while (empty)
|
||||
{
|
||||
pthread_cond_wait(&me->m_cond_request, me->m_sfx_to_play.getMutex());
|
||||
empty = me->m_sfx_to_play.getData().empty();
|
||||
pthread_cond_wait(&me->m_cond_request, me->m_sfx_commands.getMutex());
|
||||
empty = me->m_sfx_commands.getData().empty();
|
||||
}
|
||||
|
||||
SFXBase *current = me->m_sfx_to_play.getData().front();
|
||||
me->m_sfx_to_play.getData().erase(me->m_sfx_to_play.getData().begin());
|
||||
SFXCommand *current = me->m_sfx_commands.getData().front();
|
||||
me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin());
|
||||
|
||||
if (!current) // empty sfx indicates to abort the sfx manager
|
||||
if (current->m_command == SFX_EXIT)
|
||||
break;
|
||||
|
||||
me->m_sfx_to_play.unlock();
|
||||
current->reallyPlayNow();
|
||||
me->m_sfx_to_play.lock();
|
||||
me->m_sfx_commands.unlock();
|
||||
switch(current->m_command)
|
||||
{
|
||||
case SFX_PLAY: current->m_sfx->reallyPlayNow(); break;
|
||||
case SFX_STOP: current->m_sfx->reallyStopNow(); break;
|
||||
case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break;
|
||||
case SFX_RESUME: current->m_sfx->reallyResumeNow(); break;
|
||||
case SFX_SPEED: current->m_sfx->reallySetSpeed(
|
||||
current->m_parameter.getX()); break;
|
||||
case SFX_POSITION: current->m_sfx->reallySetPosition(
|
||||
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;
|
||||
}
|
||||
default: assert("Not yet supported.");
|
||||
}
|
||||
delete current;
|
||||
current = NULL;
|
||||
me->m_sfx_commands.lock();
|
||||
|
||||
} // while
|
||||
|
||||
// Clean up memory to avoid leak detection
|
||||
while(!me->m_sfx_commands.getData().empty())
|
||||
{
|
||||
delete me->m_sfx_commands.getData().front();
|
||||
me->m_sfx_commands.getData().erase(me->m_sfx_commands.getData().begin());
|
||||
}
|
||||
return NULL;
|
||||
} // mainLoop
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** Called then sound is globally switched on or off. It either pauses or
|
||||
/** Called when sound is globally switched on or off. It either pauses or
|
||||
* resumes all sound effects.
|
||||
* \param on If sound is switched on or off.
|
||||
*/
|
||||
@ -248,12 +311,13 @@ void SFXManager::soundToggled(const bool on)
|
||||
}
|
||||
|
||||
resumeAll();
|
||||
|
||||
const int sfx_amount = (int)m_all_sfx.size();
|
||||
m_all_sfx.lock();
|
||||
const int sfx_amount = (int)m_all_sfx.getData().size();
|
||||
for (int n=0; n<sfx_amount; n++)
|
||||
{
|
||||
m_all_sfx[n]->onSoundEnabledBack();
|
||||
m_all_sfx.getData()[n]->onSoundEnabledBack();
|
||||
}
|
||||
m_all_sfx.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -437,7 +501,14 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer,
|
||||
|
||||
sfx->setMasterVolume(m_master_gain);
|
||||
|
||||
if (add_to_SFX_list) m_all_sfx.push_back(sfx);
|
||||
if (add_to_SFX_list)
|
||||
{
|
||||
m_all_sfx.lock();
|
||||
m_all_sfx.getData().push_back(sfx);
|
||||
m_all_sfx.unlock();
|
||||
}
|
||||
else
|
||||
printf("");
|
||||
|
||||
return sfx;
|
||||
} // createSoundSource
|
||||
@ -497,21 +568,26 @@ void SFXManager::deleteSFXMapping(const std::string &name)
|
||||
*/
|
||||
void SFXManager::deleteSFX(SFXBase *sfx)
|
||||
{
|
||||
if(sfx) sfx->stop();
|
||||
if(sfx) sfx->reallyStopNow();
|
||||
std::vector<SFXBase*>::iterator i;
|
||||
i=std::find(m_all_sfx.begin(), m_all_sfx.end(), sfx);
|
||||
|
||||
// The whole block needs to be locked, otherwise the iterator
|
||||
// could become invalid.
|
||||
m_all_sfx.lock();
|
||||
i=std::find(m_all_sfx.getData().begin(), m_all_sfx.getData().end(), sfx);
|
||||
|
||||
if(i==m_all_sfx.end())
|
||||
if(i==m_all_sfx.getData().end())
|
||||
{
|
||||
Log::warn("SFXManager",
|
||||
"SFXManager::deleteSFX : Warning: sfx not found in list.");
|
||||
"SFXManager::deleteSFX : Warning: sfx '%s' %lx not found in list.",
|
||||
sfx->getBuffer()->getFileName().c_str(), sfx);
|
||||
return;
|
||||
}
|
||||
|
||||
m_all_sfx.getData().erase(i);
|
||||
delete sfx;
|
||||
|
||||
m_all_sfx.erase(i);
|
||||
|
||||
m_all_sfx.unlock();
|
||||
} // deleteSFX
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -521,11 +597,13 @@ void SFXManager::deleteSFX(SFXBase *sfx)
|
||||
*/
|
||||
void SFXManager::pauseAll()
|
||||
{
|
||||
for (std::vector<SFXBase*>::iterator i=m_all_sfx.begin();
|
||||
i!=m_all_sfx.end(); i++)
|
||||
m_all_sfx.lock();
|
||||
for (std::vector<SFXBase*>::iterator i= m_all_sfx.getData().begin();
|
||||
i!=m_all_sfx.getData().end(); i++)
|
||||
{
|
||||
(*i)->pause();
|
||||
} // for i in m_all_sfx
|
||||
m_all_sfx.unlock();
|
||||
} // pauseAll
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -537,19 +615,20 @@ void SFXManager::resumeAll()
|
||||
// ignore unpausing if sound is disabled
|
||||
if (!sfxAllowed()) return;
|
||||
|
||||
for (std::vector<SFXBase*>::iterator i=m_all_sfx.begin();
|
||||
i!=m_all_sfx.end(); i++)
|
||||
m_all_sfx.lock();
|
||||
for (std::vector<SFXBase*>::iterator i =m_all_sfx.getData().begin();
|
||||
i!=m_all_sfx.getData().end(); i++)
|
||||
{
|
||||
SFXStatus status = (*i)->getStatus();
|
||||
// Initial happens when
|
||||
if (status==SFX_PAUSED) (*i)->resume();
|
||||
(*i)->resume();
|
||||
} // for i in m_all_sfx
|
||||
m_all_sfx.unlock();
|
||||
} // resumeAll
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns whether or not an openal error has occurred. If so, an error
|
||||
* message is printed containing the given context.
|
||||
* \param context Context to specify in the error message.
|
||||
* \return True if no error happened.
|
||||
*/
|
||||
bool SFXManager::checkError(const std::string &context)
|
||||
{
|
||||
@ -580,11 +659,13 @@ void SFXManager::setMasterSFXVolume(float gain)
|
||||
|
||||
// regular SFX
|
||||
{
|
||||
for (std::vector<SFXBase*>::iterator i=m_all_sfx.begin();
|
||||
i!=m_all_sfx.end(); i++)
|
||||
m_all_sfx.lock();
|
||||
for (std::vector<SFXBase*>::iterator i =m_all_sfx.getData().begin();
|
||||
i!=m_all_sfx.getData().end(); i++)
|
||||
{
|
||||
(*i)->setMasterVolume(m_master_gain);
|
||||
} // for i in m_all_sfx
|
||||
m_all_sfx.unlock();
|
||||
}
|
||||
|
||||
// quick SFX
|
||||
|
@ -19,6 +19,7 @@
|
||||
#ifndef HEADER_SFX_MANAGER_HPP
|
||||
#define HEADER_SFX_MANAGER_HPP
|
||||
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
@ -57,6 +58,21 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/** The various commands to be executed by the sfx manager thread
|
||||
* for each sfx. */
|
||||
enum SFXCommands
|
||||
{
|
||||
SFX_PLAY = 1,
|
||||
SFX_STOP,
|
||||
SFX_PAUSE,
|
||||
SFX_RESUME,
|
||||
SFX_DELETE,
|
||||
SFX_SPEED,
|
||||
SFX_POSITION,
|
||||
SFX_VOLUME,
|
||||
SFX_EXIT,
|
||||
}; // SFXCommands
|
||||
|
||||
/**
|
||||
* Entries for custom SFX sounds. These are unique for each kart.
|
||||
* eg. kart->playCustomSFX(SFX_MANAGER::CUSTOM_HORN)
|
||||
@ -76,15 +92,43 @@ public:
|
||||
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:
|
||||
|
||||
/** Data structure for the queue, which stores a sfx and the command to
|
||||
* execute for it. */
|
||||
class SFXCommand : public NoCopy
|
||||
{
|
||||
private:
|
||||
LEAK_CHECK()
|
||||
public:
|
||||
/** The sound effect for which the command should be executed. */
|
||||
SFXBase *m_sfx;
|
||||
/** The command to execute. */
|
||||
SFXCommands m_command;
|
||||
/** Optional parameter for commands that need more input. */
|
||||
Vec3 m_parameter;
|
||||
// --------------------------------------------------------------------
|
||||
SFXCommand(SFXCommands command, SFXBase *base)
|
||||
{
|
||||
m_command = command;
|
||||
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 ¶meter)
|
||||
{
|
||||
m_command = command;
|
||||
m_sfx = base;
|
||||
m_parameter = parameter;
|
||||
} // SFXCommand(Vec3)
|
||||
}; // SFXCommand
|
||||
// ========================================================================
|
||||
/** Listener position */
|
||||
Vec3 m_position;
|
||||
|
||||
@ -93,10 +137,10 @@ private:
|
||||
std::map<std::string, SFXBuffer*> m_all_sfx_types;
|
||||
|
||||
/** The actual instances (sound sources) */
|
||||
std::vector<SFXBase*> m_all_sfx;
|
||||
Synchronised<std::vector<SFXBase*> > m_all_sfx;
|
||||
|
||||
/** The list of sound effects to be played in the next update. */
|
||||
Synchronised< std::vector<SFXBase*> > m_sfx_to_play;
|
||||
Synchronised< std::vector<SFXCommand*> > m_sfx_commands;
|
||||
|
||||
/** To play non-positional sounds without having to create a new object for each */
|
||||
std::map<std::string, SFXBase*> m_quick_sounds;
|
||||
@ -121,10 +165,14 @@ private:
|
||||
virtual ~SFXManager();
|
||||
|
||||
static void* mainLoop(void *obj);
|
||||
void deleteSFX(SFXBase *sfx);
|
||||
void queueCommand(SFXCommand *command);
|
||||
public:
|
||||
static void create();
|
||||
static void destroy();
|
||||
void queue(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 SFXManager *get()
|
||||
@ -153,7 +201,6 @@ public:
|
||||
SFXBase* createSoundSource(const std::string &name,
|
||||
const bool addToSFXList=true);
|
||||
|
||||
void deleteSFX(SFXBase *sfx);
|
||||
void deleteSFXMapping(const std::string &name);
|
||||
void pauseAll();
|
||||
void resumeAll();
|
||||
|
@ -23,8 +23,7 @@
|
||||
|
||||
#include "audio/sfx_buffer.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -38,18 +37,19 @@
|
||||
#include <stdio.h>
|
||||
#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_soundSource = 0;
|
||||
m_ok = false;
|
||||
m_is_playing = false;
|
||||
m_positional = positional;
|
||||
m_defaultGain = gain;
|
||||
m_loop = false;
|
||||
m_gain = -1.0f;
|
||||
m_master_gain = 1.0f;
|
||||
m_owns_buffer = ownsBuffer;
|
||||
m_sound_buffer = buffer;
|
||||
m_sound_source = 0;
|
||||
m_status = SFX_UNKNOWN;
|
||||
m_is_playing = false;
|
||||
m_positional = positional;
|
||||
m_defaultGain = gain;
|
||||
m_loop = false;
|
||||
m_gain = -1.0f;
|
||||
m_master_gain = 1.0f;
|
||||
m_owns_buffer = owns_buffer;
|
||||
m_end_time = -1.0f;
|
||||
|
||||
// Don't initialise anything else if the sfx manager was not correctly
|
||||
// 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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Deletes the sfx source, and if it owns the buffer, also deletes the sound
|
||||
* buffer. */
|
||||
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();
|
||||
delete m_soundBuffer;
|
||||
m_sound_buffer->unload();
|
||||
delete m_sound_buffer;
|
||||
}
|
||||
} // ~SFXOpenAL
|
||||
|
||||
@ -80,54 +81,78 @@ SFXOpenAL::~SFXOpenAL()
|
||||
|
||||
bool SFXOpenAL::init()
|
||||
{
|
||||
alGenSources(1, &m_soundSource );
|
||||
alGenSources(1, &m_sound_source );
|
||||
if (!SFXManager::checkError("generating a source")) return false;
|
||||
|
||||
assert( alIsBuffer(m_soundBuffer->getBufferID()) );
|
||||
assert( alIsSource(m_soundSource) );
|
||||
assert( alIsBuffer(m_sound_buffer->getBufferID()) );
|
||||
assert( alIsSource(m_sound_source) );
|
||||
|
||||
//Log::info("SFXOpenAL", "Setting a source with buffer, %p, rolloff %f, gain = %f, position = %s",
|
||||
// m_soundBuffer, rolloff, m_defaultGain, positional ? "true" : "false");
|
||||
|
||||
alSourcei (m_soundSource, AL_BUFFER, m_soundBuffer->getBufferID());
|
||||
alSourcei (m_sound_source, AL_BUFFER, m_sound_buffer->getBufferID());
|
||||
|
||||
if (!SFXManager::checkError("attaching the buffer to the source"))
|
||||
return false;
|
||||
|
||||
alSource3f(m_soundSource, AL_POSITION, 0.0, 0.0, 0.0);
|
||||
alSource3f(m_soundSource, AL_VELOCITY, 0.0, 0.0, 0.0);
|
||||
alSource3f(m_soundSource, AL_DIRECTION, 0.0, 0.0, 0.0);
|
||||
alSource3f(m_sound_source, AL_POSITION, 0.0, 0.0, 0.0);
|
||||
alSource3f(m_sound_source, AL_VELOCITY, 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_soundSource, AL_MAX_DISTANCE, m_soundBuffer->getMaxDist());
|
||||
alSourcef (m_sound_source, AL_ROLLOFF_FACTOR, m_sound_buffer->getRolloff());
|
||||
alSourcef (m_sound_source, AL_MAX_DISTANCE, m_sound_buffer->getMaxDist());
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
else alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
if (m_positional) alSourcei (m_sound_source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
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
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** 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
|
||||
*/
|
||||
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
|
||||
if(factor > 2.0f)
|
||||
{
|
||||
@ -137,23 +162,33 @@ void SFXOpenAL::speed(float factor)
|
||||
{
|
||||
factor = 0.5f;
|
||||
}
|
||||
alSourcef(m_soundSource,AL_PITCH,factor);
|
||||
SFXManager::checkError("changing the speed");
|
||||
} // speed
|
||||
alSourcef(m_sound_source,AL_PITCH,factor);
|
||||
} // reallySetSpeed
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Changes the volume of a sound effect.
|
||||
* \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;
|
||||
|
||||
if(!m_ok) return;
|
||||
if(m_status==SFX_UNKNOWN) return;
|
||||
|
||||
alSourcef(m_soundSource, AL_GAIN, m_gain * m_master_gain);
|
||||
SFXManager::checkError("setting volume");
|
||||
} // volume
|
||||
alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain);
|
||||
} // reallySetVolume
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -161,9 +196,9 @@ void SFXOpenAL::setMasterVolume(float 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);
|
||||
SFXManager::checkError("setting volume");
|
||||
} //setMasterVolume
|
||||
@ -175,54 +210,93 @@ void SFXOpenAL::setLoop(bool 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");
|
||||
} // loop
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Stops playing this sound effect.
|
||||
/** Queues a stop for this effect to the sound manager.
|
||||
*/
|
||||
void SFXOpenAL::stop()
|
||||
{
|
||||
if(!m_ok) return;
|
||||
SFXManager::get()->queue(SFXManager::SFX_STOP, this);
|
||||
} // stop
|
||||
//-----------------------------------------------------------------------------
|
||||
/** The sfx manager thread executes a stop for this sfx.
|
||||
*/
|
||||
void SFXOpenAL::reallyStopNow()
|
||||
{
|
||||
if(m_status==SFX_UNKNOWN) return;
|
||||
|
||||
m_is_playing = false;
|
||||
m_status = SFX_STOPPED;
|
||||
m_loop = false;
|
||||
alSourcei(m_soundSource, AL_LOOPING, AL_FALSE);
|
||||
alSourceStop(m_soundSource);
|
||||
alSourcei(m_sound_source, AL_LOOPING, AL_FALSE);
|
||||
alSourceStop(m_sound_source);
|
||||
SFXManager::checkError("stoping");
|
||||
} // stop
|
||||
} // reallyStopNow
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Queues up a pause command for this sfx.
|
||||
*/
|
||||
void SFXOpenAL::pause()
|
||||
{
|
||||
SFXManager::get()->queue(SFXManager::SFX_PAUSE, this);
|
||||
} // pause
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Pauses a SFX that's currently played. Nothing happens it the effect is
|
||||
* currently not being played.
|
||||
*/
|
||||
void SFXOpenAL::pause()
|
||||
void SFXOpenAL::reallyPauseNow()
|
||||
{
|
||||
if(!m_ok) return;
|
||||
alSourcePause(m_soundSource);
|
||||
if(m_status==SFX_UNKNOWN) return;
|
||||
m_status = SFX_PAUSED;
|
||||
alSourcePause(m_sound_source);
|
||||
SFXManager::checkError("pausing");
|
||||
} // pause
|
||||
} // reallyPauseNow
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Queues up a resume command for this sound effect.
|
||||
*/
|
||||
void SFXOpenAL::resume()
|
||||
{
|
||||
SFXManager::get()->queue(SFXManager::SFX_RESUME, this);
|
||||
} // resume
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Resumes a sound effect.
|
||||
*/
|
||||
void SFXOpenAL::resume()
|
||||
void SFXOpenAL::reallyResumeNow()
|
||||
{
|
||||
if (!m_ok)
|
||||
if (m_status==SFX_UNKNOWN)
|
||||
{
|
||||
// lazily create OpenAL source when needed
|
||||
init();
|
||||
|
||||
// creation of OpenAL source failed, giving up
|
||||
if (!m_ok) return;
|
||||
if (m_status==SFX_UNKNOWN) return;
|
||||
}
|
||||
|
||||
alSourcePlay(m_soundSource);
|
||||
SFXManager::checkError("resuming");
|
||||
} // resume
|
||||
if(m_status==SFX_PAUSED)
|
||||
{
|
||||
alSourcePlay(m_sound_source);
|
||||
SFXManager::checkError("resuming");
|
||||
m_status = SFX_PLAYING;
|
||||
}
|
||||
} // reallyResumeNow
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Queues up a delete request for this object. This is necessary to avoid
|
||||
* a crash if the sfx manager thread might be delayed and access this object
|
||||
* after it was deleted.
|
||||
*/
|
||||
void SFXOpenAL::deleteSFX()
|
||||
{
|
||||
SFXManager::get()->queue(SFXManager::SFX_DELETE, this);
|
||||
} // deleteSFX
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This actually queues up the sfx in the sfx manager. It will be started
|
||||
@ -234,7 +308,7 @@ void SFXOpenAL::play()
|
||||
// but for STK this is correct since we don't want to start the same
|
||||
// sfx twice.
|
||||
m_is_playing = true;
|
||||
SFXManager::get()->queue(this);
|
||||
SFXManager::get()->queue(SFXManager::SFX_PLAY, this);
|
||||
} // play
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -243,17 +317,24 @@ void SFXOpenAL::play()
|
||||
void SFXOpenAL::reallyPlayNow()
|
||||
{
|
||||
if (!SFXManager::get()->sfxAllowed()) return;
|
||||
if (!m_ok)
|
||||
if (m_status==SFX_UNKNOWN)
|
||||
{
|
||||
// lazily create OpenAL source when needed
|
||||
init();
|
||||
|
||||
// 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");
|
||||
|
||||
// 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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -268,13 +349,25 @@ bool SFXOpenAL::isPlaying()
|
||||
/** Sets the position where this sound effects is played.
|
||||
* \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)
|
||||
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;
|
||||
}
|
||||
if (!m_positional)
|
||||
@ -289,39 +382,20 @@ void SFXOpenAL::position(const Vec3 &position)
|
||||
return;
|
||||
}
|
||||
|
||||
alSource3f(m_soundSource, AL_POSITION,
|
||||
alSource3f(m_sound_source, AL_POSITION,
|
||||
(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
|
||||
{
|
||||
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");
|
||||
} // position
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** 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
|
||||
} // reallySetPosition
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -329,22 +403,22 @@ void SFXOpenAL::onSoundEnabledBack()
|
||||
{
|
||||
if (m_loop)
|
||||
{
|
||||
if (!m_ok) init();
|
||||
if (m_ok)
|
||||
if (m_status==SFX_UNKNOWN) init();
|
||||
if (m_status!=SFX_UNKNOWN)
|
||||
{
|
||||
alSourcef(m_soundSource, AL_GAIN, 0);
|
||||
alSourcef(m_sound_source, AL_GAIN, 0);
|
||||
play();
|
||||
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)
|
||||
{
|
||||
alSourcef (m_soundSource, AL_ROLLOFF_FACTOR, rolloff);
|
||||
alSourcef (m_sound_source, AL_ROLLOFF_FACTOR, rolloff);
|
||||
}
|
||||
|
||||
#endif //if HAVE_OGGVORBIS
|
||||
|
@ -28,7 +28,6 @@
|
||||
# include <AL/al.h>
|
||||
#endif
|
||||
#include "audio/sfx_base.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
|
||||
/**
|
||||
@ -38,9 +37,17 @@
|
||||
class SFXOpenAL : public SFXBase
|
||||
{
|
||||
private:
|
||||
SFXBuffer* m_soundBuffer; //!< Buffers hold sound data.
|
||||
ALuint m_soundSource; //!< Sources are points emitting sound.
|
||||
bool m_ok;
|
||||
LEAK_CHECK()
|
||||
|
||||
/** 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;
|
||||
float m_defaultGain;
|
||||
|
||||
@ -62,34 +69,44 @@ private:
|
||||
/** The master gain set in user preferences */
|
||||
float m_master_gain;
|
||||
|
||||
/** If this sfx should also free the sound 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:
|
||||
SFXOpenAL(SFXBuffer* buffer, bool positional, float gain,
|
||||
bool owns_buffer = false);
|
||||
virtual ~SFXOpenAL();
|
||||
SFXOpenAL(SFXBuffer* buffer, bool positional, float gain,
|
||||
bool owns_buffer = false);
|
||||
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();
|
||||
virtual void setLoop(bool status);
|
||||
virtual bool isPlaying();
|
||||
virtual void stop();
|
||||
virtual void pause();
|
||||
virtual void resume();
|
||||
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()
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the buffer associated with this sfx. */
|
||||
virtual const SFXBuffer* getBuffer() const { return m_sound_buffer; }
|
||||
|
||||
}; // SFXOpenAL
|
||||
|
||||
|
@ -27,13 +27,13 @@ HitSFX::HitSFX(const Vec3& coord, const char* explosion_sound)
|
||||
: HitEffect()
|
||||
{
|
||||
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
|
||||
// multiple listeners) so the sounds of all AIs are constantly heard.
|
||||
// Therefore reduce volume of sounds.
|
||||
float vol = race_manager->getNumLocalPlayers() > 1 ? 0.5f : 1.0f;
|
||||
m_sfx->volume(vol);
|
||||
m_sfx->setVolume(vol);
|
||||
m_sfx->play();
|
||||
} // HitSFX
|
||||
|
||||
@ -42,10 +42,7 @@ HitSFX::HitSFX(const Vec3& coord, const char* explosion_sound)
|
||||
*/
|
||||
HitSFX::~HitSFX()
|
||||
{
|
||||
if (m_sfx->getStatus() == SFXManager::SFX_PLAYING)
|
||||
m_sfx->stop();
|
||||
|
||||
SFXManager::get()->deleteSFX(m_sfx);
|
||||
m_sfx->deleteSFX();
|
||||
} // ~HitEffect
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -56,7 +53,7 @@ HitSFX::~HitSFX()
|
||||
void HitSFX::setPlayerKartHit()
|
||||
{
|
||||
if(race_manager->getNumLocalPlayers())
|
||||
m_sfx->volume(1.0f);
|
||||
m_sfx->setVolume(1.0f);
|
||||
} // setPlayerKartHit
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -67,7 +64,7 @@ void HitSFX::setPlayerKartHit()
|
||||
*/
|
||||
bool HitSFX::updateAndDelete(float dt)
|
||||
{
|
||||
SFXManager::SFXStatus status = m_sfx->getStatus();
|
||||
if(status==SFXManager::SFX_INITIAL) return false;
|
||||
return status!= SFXManager::SFX_PLAYING;
|
||||
SFXBase::SFXStatus status = m_sfx->getStatus();
|
||||
if(status==SFXBase::SFX_INITIAL) return false;
|
||||
return status!= SFXBase::SFX_PLAYING;
|
||||
} // updateAndDelete
|
||||
|
@ -646,14 +646,14 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) con
|
||||
if (speed < 0) speed = -speed;
|
||||
|
||||
// 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;
|
||||
// TODO: Do we first need to stop the sound completely so it
|
||||
// starts over?
|
||||
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)
|
||||
{
|
||||
@ -664,12 +664,12 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) con
|
||||
}
|
||||
if (speed > m_sfx_max_speed)
|
||||
{
|
||||
sfx->speed(m_sfx_max_pitch);
|
||||
sfx->setSpeed(m_sfx_max_pitch);
|
||||
return;
|
||||
}
|
||||
|
||||
float f = m_sfx_pitch_per_speed*(speed-m_sfx_min_speed) + m_sfx_min_pitch;
|
||||
sfx->speed(f);
|
||||
sfx->setSpeed(f);
|
||||
} // setSFXSpeed
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -51,11 +51,11 @@ Weather::Weather(bool lightning, std::string sound)
|
||||
Weather::~Weather()
|
||||
{
|
||||
if (m_thunder_sound != NULL)
|
||||
SFXManager::get()->deleteSFX(m_thunder_sound);
|
||||
m_thunder_sound->deleteSFX();
|
||||
|
||||
if (m_weather_sound != NULL)
|
||||
SFXManager::get()->deleteSFX(m_weather_sound);
|
||||
}
|
||||
m_weather_sound->deleteSFX();
|
||||
} // ~Weather
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#include <IGUIEnvironment.h>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
@ -46,6 +45,7 @@ DynamicRibbonWidget::DynamicRibbonWidget(const bool combo, const bool multi_row)
|
||||
m_check_inside_me = true;
|
||||
m_supports_multiplayer = true;
|
||||
m_scrolling_enabled = true;
|
||||
m_animated_contents = false;
|
||||
|
||||
// by default, set all players to have no selection in this ribbon
|
||||
for (unsigned int n=0; n<MAX_PLAYER_COUNT; n++)
|
||||
@ -62,7 +62,7 @@ DynamicRibbonWidget::DynamicRibbonWidget(const bool combo, const bool multi_row)
|
||||
// -----------------------------------------------------------------------------
|
||||
DynamicRibbonWidget::~DynamicRibbonWidget()
|
||||
{
|
||||
m_font->drop();
|
||||
delete m_font;
|
||||
if (m_animated_contents)
|
||||
{
|
||||
GUIEngine::needsUpdate.remove(this);
|
||||
|
@ -42,6 +42,7 @@ IconButtonWidget::IconButtonWidget(ScaleMode scale_mode, const bool tab_stop,
|
||||
m_label = NULL;
|
||||
m_font = NULL;
|
||||
m_texture = NULL;
|
||||
m_deactivated_texture = NULL;
|
||||
m_highlight_texture = NULL;
|
||||
m_custom_aspect_ratio = 1.0f;
|
||||
|
||||
@ -273,6 +274,56 @@ void IconButtonWidget::unfocused(const int playerID, Widget* new_focus)
|
||||
m_label->setVisible(false);
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
const video::ITexture* IconButtonWidget::getTexture()
|
||||
{
|
||||
if (Widget::isActivated())
|
||||
{
|
||||
return m_texture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_deactivated_texture == NULL)
|
||||
m_deactivated_texture = getDeactivatedTexture(m_texture);
|
||||
return m_deactivated_texture;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* texture)
|
||||
{
|
||||
video::ITexture* t;
|
||||
|
||||
std::string name = texture->getName().getPath().c_str();
|
||||
name += "_disabled";
|
||||
t = irr_driver->getTexture(name);
|
||||
if (t == NULL)
|
||||
{
|
||||
SColor c;
|
||||
u32 g;
|
||||
|
||||
video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
std::auto_ptr<video::IImage> image (driver->createImageFromData (texture->getColorFormat(),
|
||||
texture->getSize(), texture->lock(), false));
|
||||
texture->unlock();
|
||||
|
||||
//Turn the image into grayscale
|
||||
for (u32 x = 0; x < image->getDimension().Width; x++)
|
||||
{
|
||||
for (u32 y = 0; y < image->getDimension().Height; y++)
|
||||
{
|
||||
c = image->getPixel(x, y);
|
||||
g = ((c.getRed() + c.getGreen() + c.getBlue()) / 3);
|
||||
c.set(std::max (0, (int)c.getAlpha() - 120), g, g, g);
|
||||
image->setPixel(x, y, c);
|
||||
}
|
||||
}
|
||||
|
||||
t = driver->addTexture(name.c_str(), image.get ());
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void IconButtonWidget::setTexture(video::ITexture* texture)
|
||||
@ -280,6 +331,7 @@ void IconButtonWidget::setTexture(video::ITexture* texture)
|
||||
m_texture = texture;
|
||||
if (texture == NULL)
|
||||
{
|
||||
m_deactivated_texture = NULL;
|
||||
m_texture_w = 0;
|
||||
m_texture_h = 0;
|
||||
}
|
||||
|
@ -43,9 +43,11 @@ namespace GUIEngine
|
||||
{
|
||||
private:
|
||||
irr::video::ITexture* m_texture;
|
||||
irr::video::ITexture* m_deactivated_texture;
|
||||
irr::video::ITexture* m_highlight_texture;
|
||||
int m_texture_w, m_texture_h;
|
||||
|
||||
video::ITexture* getDeactivatedTexture(video::ITexture* texture);
|
||||
void setLabelFont();
|
||||
|
||||
public:
|
||||
@ -158,7 +160,7 @@ namespace GUIEngine
|
||||
virtual void unfocused(const int playerID, Widget* new_focus);
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the texture of this button. */
|
||||
const video::ITexture* getTexture() const { return m_texture; }
|
||||
const video::ITexture* getTexture();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -80,13 +80,13 @@ Attachment::~Attachment()
|
||||
|
||||
if (m_bomb_sound)
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_bomb_sound);
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
|
||||
if (m_bubble_explode_sound)
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_bubble_explode_sound);
|
||||
m_bubble_explode_sound->deleteSFX();
|
||||
m_bubble_explode_sound = NULL;
|
||||
}
|
||||
} // ~Attachment
|
||||
@ -139,10 +139,10 @@ void Attachment::set(AttachmentType type, float time,
|
||||
break;
|
||||
case ATTACH_BOMB:
|
||||
m_node->setMesh(attachment_manager->getMesh(type));
|
||||
if (m_bomb_sound) SFXManager::get()->deleteSFX(m_bomb_sound);
|
||||
if (m_bomb_sound) m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = SFXManager::get()->createSoundSource("clock");
|
||||
m_bomb_sound->setLoop(true);
|
||||
m_bomb_sound->position(m_kart->getXYZ());
|
||||
m_bomb_sound->setPosition(m_kart->getXYZ());
|
||||
m_bomb_sound->play();
|
||||
break;
|
||||
default:
|
||||
@ -198,8 +198,7 @@ void Attachment::clear()
|
||||
|
||||
if (m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound->stop();
|
||||
SFXManager::get()->deleteSFX(m_bomb_sound);
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
|
||||
@ -440,7 +439,7 @@ void Attachment::update(float dt)
|
||||
break;
|
||||
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)
|
||||
// The idea is change second by second, counterclockwise 60 to 0 secs
|
||||
@ -460,8 +459,7 @@ void Attachment::update(float dt)
|
||||
|
||||
if (m_bomb_sound)
|
||||
{
|
||||
m_bomb_sound->stop();
|
||||
SFXManager::get()->deleteSFX(m_bomb_sound);
|
||||
m_bomb_sound->deleteSFX();
|
||||
m_bomb_sound = NULL;
|
||||
}
|
||||
}
|
||||
@ -474,9 +472,9 @@ void Attachment::update(float dt)
|
||||
if (m_time_left < 0)
|
||||
{
|
||||
m_time_left = 0.0f;
|
||||
if (m_bubble_explode_sound) SFXManager::get()->deleteSFX(m_bubble_explode_sound);
|
||||
if (m_bubble_explode_sound) m_bubble_explode_sound->deleteSFX();
|
||||
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();
|
||||
|
||||
// drop a small bubble gum
|
||||
|
@ -87,9 +87,9 @@ Bowling::Bowling(AbstractKart *kart)
|
||||
*/
|
||||
Bowling::~Bowling()
|
||||
{
|
||||
if(m_roll_sfx->getStatus()==SFXManager::SFX_PLAYING)
|
||||
m_roll_sfx->stop();
|
||||
SFXManager::get()->deleteSFX(m_roll_sfx);
|
||||
// This will stop the sfx and delete the object.
|
||||
m_roll_sfx->deleteSFX();
|
||||
|
||||
} // ~RubberBall
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -172,8 +172,8 @@ bool Bowling::updateAndDelete(float dt)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_roll_sfx->getStatus()==SFXManager::SFX_PLAYING)
|
||||
m_roll_sfx->position(getXYZ());
|
||||
if (m_roll_sfx->getStatus()==SFXBase::SFX_PLAYING)
|
||||
m_roll_sfx->setPosition(getXYZ());
|
||||
|
||||
return false;
|
||||
} // updateAndDelete
|
||||
|
@ -53,7 +53,7 @@ Powerup::Powerup(AbstractKart* kart)
|
||||
*/
|
||||
Powerup::~Powerup()
|
||||
{
|
||||
if(m_sound_use) SFXManager::get()->deleteSFX(m_sound_use);
|
||||
if(m_sound_use) m_sound_use->deleteSFX();
|
||||
} // ~Powerup
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -88,7 +88,7 @@ void Powerup::set(PowerupManager::PowerupType type, int n)
|
||||
|
||||
if(m_sound_use != NULL)
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_sound_use);
|
||||
m_sound_use->deleteSFX();
|
||||
m_sound_use = NULL;
|
||||
}
|
||||
|
||||
@ -140,18 +140,14 @@ Material *Powerup::getIcon() const
|
||||
// Check if it's one of the types which have a separate
|
||||
// data file which includes the icon:
|
||||
return powerup_manager->getIcon(m_type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // getIcon
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Does the sound configuration.
|
||||
*/
|
||||
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)
|
||||
// so the sounds of all AIs are constantly heard. So reduce volume of sounds.
|
||||
if (race_manager->getNumLocalPlayers() > 1)
|
||||
@ -160,14 +156,16 @@ void Powerup::adjustSound()
|
||||
|
||||
if (m_owner->getController()->isPlayerController())
|
||||
{
|
||||
m_sound_use->volume( 1.0f );
|
||||
m_sound_use->setVolume( 1.0f );
|
||||
}
|
||||
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.
|
||||
*/
|
||||
@ -205,7 +203,7 @@ void Powerup::use()
|
||||
case PowerupManager::POWERUP_SWITCH:
|
||||
{
|
||||
ItemManager::get()->switchItems();
|
||||
m_sound_use->position(m_owner->getXYZ());
|
||||
m_sound_use->setPosition(m_owner->getXYZ());
|
||||
m_sound_use->play();
|
||||
break;
|
||||
}
|
||||
@ -310,9 +308,9 @@ void Powerup::use()
|
||||
// Meanwhile, don't play it near AI karts since they obviously
|
||||
// don't hear anything
|
||||
if(kart->getController()->isPlayerController())
|
||||
m_sound_use->position(kart->getXYZ());
|
||||
m_sound_use->setPosition(kart->getXYZ());
|
||||
else
|
||||
m_sound_use->position(m_owner->getXYZ());
|
||||
m_sound_use->setPosition(m_owner->getXYZ());
|
||||
|
||||
m_sound_use->play();
|
||||
break;
|
||||
@ -352,9 +350,9 @@ void Powerup::use()
|
||||
// Meanwhile, don't play it near AI karts since they obviously
|
||||
// don't hear anything
|
||||
if(m_owner->getController()->isPlayerController())
|
||||
m_sound_use->position(m_owner->getXYZ());
|
||||
m_sound_use->setPosition(m_owner->getXYZ());
|
||||
else if(player_kart)
|
||||
m_sound_use->position(player_kart->getXYZ());
|
||||
m_sound_use->setPosition(player_kart->getXYZ());
|
||||
m_sound_use->play();
|
||||
}
|
||||
break;
|
||||
|
@ -107,9 +107,9 @@ RubberBall::RubberBall(AbstractKart *kart)
|
||||
*/
|
||||
RubberBall::~RubberBall()
|
||||
{
|
||||
if(m_ping_sfx->getStatus()==SFXManager::SFX_PLAYING)
|
||||
if(m_ping_sfx->getStatus()==SFXBase::SFX_PLAYING)
|
||||
m_ping_sfx->stop();
|
||||
SFXManager::get()->deleteSFX(m_ping_sfx);
|
||||
m_ping_sfx->deleteSFX();
|
||||
} // ~RubberBall
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -541,9 +541,9 @@ float RubberBall::updateHeight()
|
||||
if(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();
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ Swatter::~Swatter()
|
||||
}
|
||||
if (m_swat_sound)
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_swat_sound);
|
||||
m_swat_sound->deleteSFX();
|
||||
}
|
||||
} // ~Swatter
|
||||
|
||||
@ -275,7 +275,7 @@ void Swatter::squashThingsAround()
|
||||
assert(swatter_node);
|
||||
Vec3 swatter_pos = swatter_node->getAbsolutePosition();
|
||||
|
||||
m_swat_sound->position(swatter_pos);
|
||||
m_swat_sound->setPosition(swatter_pos);
|
||||
m_swat_sound->play();
|
||||
|
||||
// Squash karts around
|
||||
|
@ -74,11 +74,11 @@ PlayerController::PlayerController(AbstractKart *kart,
|
||||
*/
|
||||
PlayerController::~PlayerController()
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_bzzt_sound);
|
||||
SFXManager::get()->deleteSFX(m_wee_sound );
|
||||
SFXManager::get()->deleteSFX(m_ugh_sound );
|
||||
SFXManager::get()->deleteSFX(m_grab_sound);
|
||||
SFXManager::get()->deleteSFX(m_full_sound);
|
||||
m_bzzt_sound->deleteSFX();
|
||||
m_wee_sound ->deleteSFX();
|
||||
m_ugh_sound ->deleteSFX();
|
||||
m_grab_sound->deleteSFX();
|
||||
m_full_sound->deleteSFX();
|
||||
} // ~PlayerController
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -439,7 +439,7 @@ void PlayerController::handleZipper(bool play_sound)
|
||||
// Only play a zipper sound if it's not already playing, and
|
||||
// if the material has changed (to avoid machine gun effect
|
||||
// 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_wee_sound->play();
|
||||
|
@ -183,19 +183,19 @@ void Kart::init(RaceManager::KartType type)
|
||||
{
|
||||
// players have louder sounds than AIs
|
||||
const float factor = std::min(1.0f, race_manager->getNumLocalPlayers()/2.0f);
|
||||
m_goo_sound->volume( 1.0f / factor );
|
||||
m_skid_sound->volume( 1.0f / factor );
|
||||
m_crash_sound->volume( 1.0f / factor );
|
||||
m_boing_sound->volume( 1.0f / factor );
|
||||
m_beep_sound->volume( 1.0f / factor );
|
||||
m_goo_sound->setVolume( 1.0f / factor );
|
||||
m_skid_sound->setVolume( 1.0f / factor );
|
||||
m_crash_sound->setVolume( 1.0f / factor );
|
||||
m_boing_sound->setVolume( 1.0f / factor );
|
||||
m_beep_sound->setVolume( 1.0f / factor );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_goo_sound->volume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_skid_sound->volume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_crash_sound->volume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_beep_sound->volume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_boing_sound->volume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_goo_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_skid_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_crash_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_beep_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
m_boing_sound->setVolume( 1.0f / race_manager->getNumberOfKarts() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,15 +246,15 @@ Kart::~Kart()
|
||||
SFXManager::get()->deleteSFX(m_custom_sounds[n]);
|
||||
}*/
|
||||
|
||||
SFXManager::get()->deleteSFX(m_engine_sound );
|
||||
SFXManager::get()->deleteSFX(m_crash_sound );
|
||||
SFXManager::get()->deleteSFX(m_skid_sound );
|
||||
SFXManager::get()->deleteSFX(m_goo_sound );
|
||||
SFXManager::get()->deleteSFX(m_beep_sound );
|
||||
SFXManager::get()->deleteSFX(m_boing_sound );
|
||||
m_engine_sound->deleteSFX();
|
||||
m_crash_sound ->deleteSFX();
|
||||
m_skid_sound ->deleteSFX();
|
||||
m_goo_sound ->deleteSFX();
|
||||
m_beep_sound ->deleteSFX();
|
||||
m_boing_sound ->deleteSFX();
|
||||
delete m_kart_gfx;
|
||||
if(m_terrain_sound) SFXManager::get()->deleteSFX(m_terrain_sound);
|
||||
if(m_previous_terrain_sound) SFXManager::get()->deleteSFX(m_previous_terrain_sound);
|
||||
if(m_terrain_sound) m_terrain_sound->deleteSFX();
|
||||
if(m_previous_terrain_sound) m_previous_terrain_sound->deleteSFX();
|
||||
if(m_collision_particles) delete m_collision_particles;
|
||||
if(m_slipstream) delete m_slipstream;
|
||||
if(m_sky_particles_emitter) delete m_sky_particles_emitter;
|
||||
@ -363,16 +363,15 @@ void Kart::reset()
|
||||
|
||||
if(m_terrain_sound)
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_terrain_sound);
|
||||
m_terrain_sound->deleteSFX();
|
||||
m_terrain_sound = NULL;
|
||||
}
|
||||
if(m_previous_terrain_sound)
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_previous_terrain_sound);
|
||||
m_previous_terrain_sound->deleteSFX();
|
||||
m_previous_terrain_sound = NULL;
|
||||
}
|
||||
|
||||
m_terrain_sound = NULL;
|
||||
m_previous_terrain_sound = NULL;
|
||||
|
||||
if(m_engine_sound)
|
||||
m_engine_sound->stop();
|
||||
|
||||
@ -757,12 +756,12 @@ void Kart::startEngineSFX()
|
||||
const float players_volume = (np * 2.0f) / (np*2.0f + np);
|
||||
|
||||
if (m_controller->isPlayerController())
|
||||
m_engine_sound->volume( players_volume / np );
|
||||
m_engine_sound->setVolume( players_volume / np );
|
||||
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->play();
|
||||
} // startEngineSFX
|
||||
@ -929,7 +928,7 @@ void Kart::collectedItem(Item *item, int add_info)
|
||||
m_kart_properties->getBubblegumSpeedFraction(),
|
||||
m_kart_properties->getBubblegumFadeInTime(),
|
||||
m_bubblegum_time);
|
||||
m_goo_sound->position(getXYZ());
|
||||
m_goo_sound->setPosition(getXYZ());
|
||||
m_goo_sound->play();
|
||||
// Play appropriate custom character sound
|
||||
playCustomSFX(SFXManager::CUSTOM_GOO);
|
||||
@ -1185,11 +1184,11 @@ void Kart::update(float dt)
|
||||
}
|
||||
*/
|
||||
|
||||
m_beep_sound->position ( getXYZ() );
|
||||
m_engine_sound->position ( getXYZ() );
|
||||
m_crash_sound->position ( getXYZ() );
|
||||
m_skid_sound->position ( getXYZ() );
|
||||
m_boing_sound->position ( getXYZ() );
|
||||
m_beep_sound->setPosition ( getXYZ() );
|
||||
m_engine_sound->setPosition ( getXYZ() );
|
||||
m_crash_sound->setPosition ( getXYZ() );
|
||||
m_skid_sound->setPosition ( getXYZ() );
|
||||
m_boing_sound->setPosition ( getXYZ() );
|
||||
|
||||
// Check if a kart is (nearly) upside down and not moving much -->
|
||||
// automatic rescue
|
||||
@ -1430,7 +1429,7 @@ void Kart::handleMaterialSFX(const Material *material)
|
||||
// can be used again.
|
||||
if(m_previous_terrain_sound)
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_previous_terrain_sound);
|
||||
m_previous_terrain_sound->deleteSFX();
|
||||
}
|
||||
m_previous_terrain_sound = m_terrain_sound;
|
||||
if(m_previous_terrain_sound)
|
||||
@ -1448,7 +1447,7 @@ void Kart::handleMaterialSFX(const Material *material)
|
||||
{
|
||||
if (!m_controller->isPlayerController())
|
||||
{
|
||||
m_terrain_sound->volume( 0.0f );
|
||||
m_terrain_sound->setVolume( 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
@ -1462,12 +1461,12 @@ void Kart::handleMaterialSFX(const Material *material)
|
||||
}
|
||||
|
||||
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
|
||||
// anymore, so that it keeps on playing at the place where the
|
||||
// kart left the material.
|
||||
SFXManager::get()->deleteSFX(m_previous_terrain_sound);
|
||||
m_previous_terrain_sound->deleteSFX();
|
||||
m_previous_terrain_sound = NULL;
|
||||
}
|
||||
|
||||
@ -1478,10 +1477,10 @@ void Kart::handleMaterialSFX(const Material *material)
|
||||
// terrain sound is not necessarily a looping sound so check its status before
|
||||
// setting its speed, to avoid 'ressuscitating' sounds that had already stopped
|
||||
if(m_terrain_sound &&
|
||||
(m_terrain_sound->getStatus()==SFXManager::SFX_PLAYING ||
|
||||
m_terrain_sound->getStatus()==SFXManager::SFX_PAUSED))
|
||||
(m_terrain_sound->getStatus()==SFXBase::SFX_PLAYING ||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1590,9 +1589,9 @@ void Kart::handleMaterialGFX()
|
||||
const std::string &s = surface_material->getSFXName();
|
||||
if (s != "" && !dynamic_cast<RescueAnimation*>(getKartAnimation())&&
|
||||
(m_terrain_sound == NULL ||
|
||||
m_terrain_sound->getStatus() == SFXManager::SFX_STOPPED))
|
||||
m_terrain_sound->getStatus() == SFXBase::SFX_STOPPED))
|
||||
{
|
||||
if (m_previous_terrain_sound) SFXManager::get()->deleteSFX(m_previous_terrain_sound);
|
||||
if (m_previous_terrain_sound) m_previous_terrain_sound->deleteSFX();
|
||||
m_previous_terrain_sound = m_terrain_sound;
|
||||
if(m_previous_terrain_sound)
|
||||
m_previous_terrain_sound->setLoop(false);
|
||||
@ -1893,12 +1892,12 @@ void Kart::crashed(const Material* m, AbstractKart *k)
|
||||
// it's not already playing.
|
||||
if (isShielded() || (k != NULL && k->isShielded()))
|
||||
{
|
||||
if (!m_boing_sound->isPlaying())
|
||||
if (m_boing_sound->getStatus() != SFXBase::SFX_PLAYING)
|
||||
m_boing_sound->play();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!m_crash_sound->isPlaying())
|
||||
if(m_crash_sound->getStatus() != SFXBase::SFX_PLAYING)
|
||||
m_crash_sound->play();
|
||||
}
|
||||
}
|
||||
@ -1973,7 +1972,7 @@ bool Kart::playCustomSFX(unsigned int type)
|
||||
// SFXManager::get()->getCustomTagName(type),
|
||||
// m_kart_properties->getIdent().c_str());
|
||||
// If it's already playing, let it finish
|
||||
if (!m_custom_sounds[type]->isPlaying())
|
||||
if (m_custom_sounds[type]->getStatus() != SFXManager::SFX_PLAYING)
|
||||
{
|
||||
m_custom_sounds[type]->play();
|
||||
}
|
||||
@ -2124,15 +2123,15 @@ void Kart::updateEngineSFX()
|
||||
if (f>1.0f) f=1.0f;
|
||||
|
||||
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
|
||||
{
|
||||
// When flying, fixed value but not too high pitch
|
||||
// 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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -73,7 +73,7 @@ void LinearWorld::init()
|
||||
*/
|
||||
LinearWorld::~LinearWorld()
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_last_lap_sfx);
|
||||
m_last_lap_sfx->deleteSFX();
|
||||
} // ~LinearWorld
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -155,7 +155,7 @@ void LinearWorld::update(float dt)
|
||||
WorldWithRank::update(dt);
|
||||
|
||||
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())
|
||||
music_manager->getCurrentMusic()->resetTemporaryVolume();
|
||||
|
@ -60,7 +60,7 @@ SoccerWorld::SoccerWorld() : WorldWithRank()
|
||||
*/
|
||||
SoccerWorld::~SoccerWorld()
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_goal_sound);
|
||||
m_goal_sound->deleteSFX();
|
||||
} // ~SoccerWorld
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -121,7 +121,7 @@ void SoccerWorld::reset()
|
||||
}
|
||||
|
||||
if (m_goal_sound != NULL &&
|
||||
m_goal_sound->getStatus() == SFXManager::SFX_PLAYING)
|
||||
m_goal_sound->getStatus() == SFXBase::SFX_PLAYING)
|
||||
{
|
||||
m_goal_sound->stop();
|
||||
}
|
||||
|
@ -74,9 +74,9 @@ void WorldStatus::reset()
|
||||
*/
|
||||
WorldStatus::~WorldStatus()
|
||||
{
|
||||
SFXManager::get()->deleteSFX(m_prestart_sound);
|
||||
SFXManager::get()->deleteSFX(m_start_sound);
|
||||
SFXManager::get()->deleteSFX(m_track_intro_sound);
|
||||
m_prestart_sound->deleteSFX();
|
||||
m_start_sound->deleteSFX();
|
||||
m_track_intro_sound->deleteSFX();
|
||||
IrrlichtDevice *device = irr_driver->getDevice();
|
||||
|
||||
if (device->getTimer()->isStopped())
|
||||
@ -162,7 +162,7 @@ void WorldStatus::update(const float dt)
|
||||
// ... phase. Since the sound effect is about 3 seconds
|
||||
// long, we use the aux timer to force the next phase
|
||||
// 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)
|
||||
return;
|
||||
|
||||
|
@ -247,8 +247,6 @@ btScalar btKart::rayCast(unsigned int index)
|
||||
wheel.m_raycastInfo.m_contactPointWS = source + rayvector;
|
||||
const btVector3& target = wheel.m_raycastInfo.m_contactPointWS;
|
||||
|
||||
btScalar param = btScalar(0.);
|
||||
|
||||
btVehicleRaycaster::btVehicleRaycasterResult rayResults;
|
||||
|
||||
btAssert(m_vehicleRaycaster);
|
||||
|
@ -138,7 +138,7 @@ void OptionsScreenAudio::eventCallback(Widget* widget, const std::string& name,
|
||||
assert(w != NULL);
|
||||
|
||||
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 );
|
||||
UserConfigParams::m_sfx_volume = w->getValue()/10.0f;
|
||||
|
@ -116,7 +116,7 @@ void RaceResultGUI::tearDown()
|
||||
m_font->setMonospaceDigits(m_was_monospace);
|
||||
|
||||
if (m_finish_sound != NULL &&
|
||||
m_finish_sound->getStatus() == SFXManager::SFX_PLAYING)
|
||||
m_finish_sound->getStatus() == SFXBase::SFX_PLAYING)
|
||||
{
|
||||
m_finish_sound->stop();
|
||||
}
|
||||
@ -600,7 +600,7 @@ void RaceResultGUI::onUpdate(float dt)
|
||||
renderGlobal(dt);
|
||||
|
||||
if (m_finish_sound != NULL &&
|
||||
m_finish_sound->getStatus() != SFXManager::SFX_PLAYING)
|
||||
m_finish_sound->getStatus() != SFXBase::SFX_PLAYING)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -70,6 +70,16 @@ void TrackInfoScreen::loadedFromFile()
|
||||
m_ai_kart_spinner = getWidget<SpinnerWidget>("ai-spinner");
|
||||
m_reverse = getWidget<CheckBoxWidget>("reverse");
|
||||
m_reverse->setState(false);
|
||||
|
||||
m_highscore_label = getWidget<LabelWidget>("highscores");
|
||||
|
||||
m_kart_icons[0] = getWidget<IconButtonWidget>("iconscore1");
|
||||
m_kart_icons[1] = getWidget<IconButtonWidget>("iconscore2");
|
||||
m_kart_icons[2] = getWidget<IconButtonWidget>("iconscore3");
|
||||
|
||||
m_highscore_entries[0] = getWidget<LabelWidget>("highscore1");
|
||||
m_highscore_entries[1] = getWidget<LabelWidget>("highscore2");
|
||||
m_highscore_entries[2] = getWidget<LabelWidget>("highscore3");
|
||||
} // loadedFromFile
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -181,30 +191,16 @@ void TrackInfoScreen::init()
|
||||
m_reverse->setState(false);
|
||||
|
||||
// ---- High Scores
|
||||
if (has_highscores)
|
||||
{
|
||||
m_kart_icons[0] = getWidget<IconButtonWidget>("iconscore1");
|
||||
m_kart_icons[1] = getWidget<IconButtonWidget>("iconscore2");
|
||||
m_kart_icons[2] = getWidget<IconButtonWidget>("iconscore3");
|
||||
m_highscore_label->setVisible(has_highscores);
|
||||
|
||||
m_highscore_entries[0] = getWidget<LabelWidget>("highscore1");
|
||||
m_highscore_entries[1] = getWidget<LabelWidget>("highscore2");
|
||||
m_highscore_entries[2] = getWidget<LabelWidget>("highscore3");
|
||||
m_kart_icons[0]->setVisible(has_highscores);
|
||||
m_kart_icons[1]->setVisible(has_highscores);
|
||||
m_kart_icons[2]->setVisible(has_highscores);
|
||||
|
||||
updateHighScores();
|
||||
}
|
||||
else
|
||||
{
|
||||
getWidget<IconButtonWidget>("iconscore1")->setVisible(false);
|
||||
getWidget<IconButtonWidget>("iconscore2")->setVisible(false);
|
||||
getWidget<IconButtonWidget>("iconscore3")->setVisible(false);
|
||||
m_highscore_entries[0]->setVisible(has_highscores);
|
||||
m_highscore_entries[1]->setVisible(has_highscores);
|
||||
m_highscore_entries[2]->setVisible(has_highscores);
|
||||
|
||||
getWidget<LabelWidget>("highscores")->setVisible(false);
|
||||
getWidget<LabelWidget>("highscore1")->setVisible(false);
|
||||
getWidget<LabelWidget>("highscore2")->setVisible(false);
|
||||
getWidget<LabelWidget>("highscore3")->setVisible(false);
|
||||
}
|
||||
|
||||
RibbonWidget* bt_start = getWidget<GUIEngine::RibbonWidget>("buttons");
|
||||
bt_start->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
@ -220,6 +216,9 @@ TrackInfoScreen::~TrackInfoScreen()
|
||||
|
||||
void TrackInfoScreen::updateHighScores()
|
||||
{
|
||||
if (!race_manager->modeHasHighscores())
|
||||
return;
|
||||
|
||||
std::string game_mode_ident = RaceManager::getIdentOf( race_manager->getMinorMode() );
|
||||
const Highscores::HighscoreType type = "HST_" + game_mode_ident;
|
||||
|
||||
@ -281,7 +280,7 @@ void TrackInfoScreen::onEnterPressedInternal()
|
||||
|
||||
// Create a copy of member variables we still need, since they will
|
||||
// not be accessible after dismiss:
|
||||
const int num_laps = race_manager->modeHasLaps() ? m_lap_spinner->getValue()
|
||||
const int num_laps = race_manager->modeHasLaps() ? m_lap_spinner->getValue()
|
||||
: -1;
|
||||
const bool reverse_track = m_reverse == NULL ? false
|
||||
: m_reverse->getState();
|
||||
@ -318,10 +317,7 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
race_manager->setReverseTrack(m_reverse->getState());
|
||||
// Makes sure the highscores get swapped when clicking the 'reverse'
|
||||
// checkbox.
|
||||
if (race_manager->modeHasHighscores())
|
||||
{
|
||||
updateHighScores();
|
||||
}
|
||||
updateHighScores();
|
||||
}
|
||||
else if (name == "lap-spinner")
|
||||
{
|
||||
|
@ -58,18 +58,21 @@ class TrackInfoScreen : public GUIEngine::Screen,
|
||||
/** Check box for reverse mode. */
|
||||
GUIEngine::CheckBoxWidget* m_reverse;
|
||||
|
||||
/** The label of the highscore list. */
|
||||
GUIEngine::LabelWidget* m_highscore_label;
|
||||
|
||||
/** The icons for the highscore list. */
|
||||
GUIEngine::IconButtonWidget* m_kart_icons[HIGHSCORE_COUNT];
|
||||
|
||||
/** The actual highscore text values shown. */
|
||||
GUIEngine::LabelWidget* m_highscore_entries[HIGHSCORE_COUNT];
|
||||
|
||||
|
||||
void updateHighScores();
|
||||
|
||||
|
||||
public:
|
||||
TrackInfoScreen();
|
||||
virtual ~TrackInfoScreen();
|
||||
|
||||
|
||||
virtual void init();
|
||||
virtual void loadedFromFile();
|
||||
virtual void eventCallback(GUIEngine::Widget *,const std::string &name ,
|
||||
|
@ -1419,6 +1419,9 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml)
|
||||
continue;
|
||||
}
|
||||
|
||||
// to lower case, for case-insensitive comparison
|
||||
name = StringUtils::toLowerCase(name);
|
||||
|
||||
for(unsigned int i=0; i<node->getMaterialCount(); i++)
|
||||
{
|
||||
video::SMaterial &irrMaterial=node->getMaterial(i);
|
||||
@ -1426,9 +1429,13 @@ void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml)
|
||||
{
|
||||
video::ITexture* t=irrMaterial.getTexture(j);
|
||||
if(!t) continue;
|
||||
const std::string texture_name =
|
||||
std::string texture_name =
|
||||
StringUtils::getBasename(core::stringc(t->getName()).c_str());
|
||||
if(texture_name!=name) continue;
|
||||
|
||||
// to lower case, for case-insensitive comparison
|
||||
texture_name = StringUtils::toLowerCase(texture_name);
|
||||
|
||||
if (texture_name != name) continue;
|
||||
core::matrix4 *m = &irrMaterial.getTextureMatrix(j);
|
||||
m_animated_textures.push_back(new MovingTexture(m, *texture_node));
|
||||
} // for j<MATERIAL_MAX_TEXTURES
|
||||
|
@ -382,8 +382,9 @@ void TrackObjectPresentationMesh::reset()
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_node, scene::ISceneNode* parent) :
|
||||
TrackObjectPresentation(xml_node)
|
||||
TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_node,
|
||||
scene::ISceneNode* parent)
|
||||
: TrackObjectPresentation(xml_node)
|
||||
{
|
||||
// TODO: respect 'parent' if any
|
||||
|
||||
@ -426,7 +427,7 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_no
|
||||
m_sound = SFXManager::get()->createSoundSource(buffer, true, true);
|
||||
if (m_sound != NULL)
|
||||
{
|
||||
m_sound->position(m_init_xyz);
|
||||
m_sound->setPosition(m_init_xyz);
|
||||
if (!trigger_when_near && m_trigger_condition.empty())
|
||||
{
|
||||
m_sound->setLoop(true);
|
||||
@ -440,8 +441,9 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_no
|
||||
{
|
||||
ItemManager::get()->newItem(m_init_xyz, trigger_distance, this);
|
||||
}
|
||||
}
|
||||
} // TrackObjectPresentationSound
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackObjectPresentationSound::update(float dt)
|
||||
{
|
||||
if (m_sound != NULL)
|
||||
@ -449,18 +451,20 @@ void TrackObjectPresentationSound::update(float dt)
|
||||
// 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
|
||||
// moved
|
||||
m_sound->position(m_xyz);
|
||||
m_sound->setPosition(m_xyz);
|
||||
}
|
||||
}
|
||||
} // update
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
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();
|
||||
}
|
||||
}
|
||||
} // onTriggerItemApproached
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackObjectPresentationSound::triggerSound(bool loop)
|
||||
{
|
||||
if (m_sound != NULL)
|
||||
@ -468,34 +472,37 @@ void TrackObjectPresentationSound::triggerSound(bool loop)
|
||||
m_sound->setLoop(loop);
|
||||
m_sound->play();
|
||||
}
|
||||
}
|
||||
} // triggerSound
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackObjectPresentationSound::stopSound()
|
||||
{
|
||||
if (m_sound != NULL) m_sound->stop();
|
||||
}
|
||||
} // stopSound
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
TrackObjectPresentationSound::~TrackObjectPresentationSound()
|
||||
{
|
||||
if (m_sound)
|
||||
{
|
||||
//delete m_sound->getBuffer();
|
||||
SFXManager::get()->deleteSFX(m_sound);
|
||||
m_sound->deleteSFX();
|
||||
}
|
||||
}
|
||||
} // ~TrackObjectPresentationSound
|
||||
|
||||
void TrackObjectPresentationSound::move(const core::vector3df& xyz, const core::vector3df& hpr,
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackObjectPresentationSound::move(const core::vector3df& xyz,
|
||||
const core::vector3df& hpr,
|
||||
const core::vector3df& scale)
|
||||
{
|
||||
m_xyz = xyz;
|
||||
if (m_sound != NULL) m_sound->position(xyz);
|
||||
}
|
||||
if (m_sound != NULL) m_sound->setPosition(xyz);
|
||||
} // move
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode& xml_node, scene::ISceneNode* parent) :
|
||||
TrackObjectPresentationSceneNode(xml_node)
|
||||
TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode& xml_node,
|
||||
scene::ISceneNode* parent)
|
||||
: TrackObjectPresentationSceneNode(xml_node)
|
||||
{
|
||||
std::string texture_name;
|
||||
float width, height;
|
||||
@ -529,6 +536,7 @@ TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode
|
||||
m_node->setPosition(m_init_xyz);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackObjectPresentationBillboard::update(float dt)
|
||||
{
|
||||
if (m_fade_out_when_close)
|
||||
@ -554,6 +562,7 @@ void TrackObjectPresentationBillboard::update(float dt)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
TrackObjectPresentationBillboard::~TrackObjectPresentationBillboard()
|
||||
{
|
||||
if (m_node)
|
||||
@ -613,6 +622,7 @@ TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
TrackObjectPresentationParticles::~TrackObjectPresentationParticles()
|
||||
{
|
||||
if (m_emitter)
|
||||
@ -626,6 +636,7 @@ TrackObjectPresentationParticles::~TrackObjectPresentationParticles()
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackObjectPresentationParticles::update(float dt)
|
||||
{
|
||||
if (m_emitter != NULL)
|
||||
@ -634,6 +645,7 @@ void TrackObjectPresentationParticles::update(float dt)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackObjectPresentationParticles::triggerParticles()
|
||||
{
|
||||
if (m_emitter != NULL)
|
||||
@ -671,6 +683,7 @@ TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_no
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
TrackObjectPresentationLight::~TrackObjectPresentationLight()
|
||||
{
|
||||
}
|
||||
@ -693,6 +706,7 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(const
|
||||
ItemManager::get()->newItem(m_init_xyz, trigger_distance, this);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void TrackObjectPresentationActionTrigger::onTriggerItemApproached(Item* who)
|
||||
{
|
||||
if (!m_action_active) return;
|
||||
|
Loading…
Reference in New Issue
Block a user