From 3fc0d3be0930f3e11f7845f352cf38c65fecb43a Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Fri, 3 Oct 2014 16:25:19 +0200 Subject: [PATCH 01/15] Second try of my previous pull request, which was partially reverted due to caused crashes and memory leaks --- src/guiengine/widgets/icon_button_widget.cpp | 45 ++++++++++++++++++++ src/guiengine/widgets/icon_button_widget.hpp | 4 +- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index 4255895a0..f384bd83e 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -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; @@ -270,6 +271,49 @@ 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) +{ + SColor c; + u32 g; + + video::IVideoDriver* driver = irr_driver->getVideoDriver(); + 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); + } + } + + texture = driver->addTexture(texture->getName().getPath() + "_disabled", image); + image->drop(); + + return texture; +} // ----------------------------------------------------------------------------- void IconButtonWidget::setTexture(video::ITexture* texture) @@ -277,6 +321,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; } diff --git a/src/guiengine/widgets/icon_button_widget.hpp b/src/guiengine/widgets/icon_button_widget.hpp index e4126ab91..9c8221a87 100644 --- a/src/guiengine/widgets/icon_button_widget.hpp +++ b/src/guiengine/widgets/icon_button_widget.hpp @@ -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(); }; } From f520e38cd5df1d8ad71e6128e61db258622f6f3d Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Fri, 3 Oct 2014 22:11:21 +0200 Subject: [PATCH 02/15] This will (hopefully) solve the memory leaks in dynamic ribbons and image button widgets --- src/guiengine/widgets/dynamic_ribbon_widget.cpp | 4 ++-- src/guiengine/widgets/icon_button_widget.cpp | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index 34fdf011a..f3b013873 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -23,7 +23,6 @@ #include "utils/vs.hpp" #include -#include #include #include @@ -45,6 +44,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; ndrop(); + delete m_font; if (m_animated_contents) { GUIEngine::needsUpdate.remove(this); diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index f384bd83e..393858ed9 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -293,8 +293,8 @@ video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* textur u32 g; video::IVideoDriver* driver = irr_driver->getVideoDriver(); - video::IImage* image = driver->createImageFromData (texture->getColorFormat(), - texture->getSize(), texture->lock(), false); + std::auto_ptr image (driver->createImageFromData (texture->getColorFormat(), + texture->getSize(), texture->lock(), false)); texture->unlock(); //Turn the image into grayscale @@ -309,10 +309,7 @@ video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* textur } } - texture = driver->addTexture(texture->getName().getPath() + "_disabled", image); - image->drop(); - - return texture; + return driver->addTexture(texture->getName().getPath() + "_disabled", image.get ()); } // ----------------------------------------------------------------------------- From ee49604856fcc601a547f36d579e554443ec6895 Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Sat, 4 Oct 2014 12:15:11 +0200 Subject: [PATCH 03/15] Issue #1588 Fixed crashes in track info screen --- src/states_screens/track_info_screen.cpp | 48 +++++++++++------------- src/states_screens/track_info_screen.hpp | 9 +++-- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/states_screens/track_info_screen.cpp b/src/states_screens/track_info_screen.cpp index fd089f376..b54c100ba 100644 --- a/src/states_screens/track_info_screen.cpp +++ b/src/states_screens/track_info_screen.cpp @@ -70,6 +70,16 @@ void TrackInfoScreen::loadedFromFile() m_ai_kart_spinner = getWidget("ai-spinner"); m_reverse = getWidget("reverse"); m_reverse->setState(false); + + m_highscore_label = getWidget("highscores"); + + m_kart_icons[0] = getWidget("iconscore1"); + m_kart_icons[1] = getWidget("iconscore2"); + m_kart_icons[2] = getWidget("iconscore3"); + + m_highscore_entries[0] = getWidget("highscore1"); + m_highscore_entries[1] = getWidget("highscore2"); + m_highscore_entries[2] = getWidget("highscore3"); } // loadedFromFile // ---------------------------------------------------------------------------- @@ -181,30 +191,16 @@ void TrackInfoScreen::init() m_reverse->setState(false); // ---- High Scores - if (has_highscores) - { - m_kart_icons[0] = getWidget("iconscore1"); - m_kart_icons[1] = getWidget("iconscore2"); - m_kart_icons[2] = getWidget("iconscore3"); + m_highscore_label->setVisible(has_highscores); - m_highscore_entries[0] = getWidget("highscore1"); - m_highscore_entries[1] = getWidget("highscore2"); - m_highscore_entries[2] = getWidget("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("iconscore1")->setVisible(false); - getWidget("iconscore2")->setVisible(false); - getWidget("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("highscores")->setVisible(false); - getWidget("highscore1")->setVisible(false); - getWidget("highscore2")->setVisible(false); - getWidget("highscore3")->setVisible(false); - } - RibbonWidget* bt_start = getWidget("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") { diff --git a/src/states_screens/track_info_screen.hpp b/src/states_screens/track_info_screen.hpp index 4034bd5de..e84173d6a 100644 --- a/src/states_screens/track_info_screen.hpp +++ b/src/states_screens/track_info_screen.hpp @@ -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 , From 9b57d76a796df8b2dded733329f0bd3e125a514b Mon Sep 17 00:00:00 2001 From: Marc Coll Carrillo Date: Tue, 7 Oct 2014 18:27:08 +0200 Subject: [PATCH 04/15] Check texture cache before adding an icon button's disabled texture --- src/guiengine/widgets/icon_button_widget.cpp | 40 ++++++++++++-------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/guiengine/widgets/icon_button_widget.cpp b/src/guiengine/widgets/icon_button_widget.cpp index 393858ed9..d194c3630 100644 --- a/src/guiengine/widgets/icon_button_widget.cpp +++ b/src/guiengine/widgets/icon_button_widget.cpp @@ -289,27 +289,37 @@ const video::ITexture* IconButtonWidget::getTexture() // ----------------------------------------------------------------------------- video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* texture) { - SColor c; - u32 g; + video::ITexture* t; - video::IVideoDriver* driver = irr_driver->getVideoDriver(); - std::auto_ptr 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++) + std::string name = texture->getName().getPath().c_str(); + name += "_disabled"; + t = irr_driver->getTexture(name); + if (t == NULL) { - for (u32 y = 0; y < image->getDimension().Height; y++) + SColor c; + u32 g; + + video::IVideoDriver* driver = irr_driver->getVideoDriver(); + std::auto_ptr 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++) { - 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); + 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 driver->addTexture(texture->getName().getPath() + "_disabled", image.get ()); + return t; } // ----------------------------------------------------------------------------- From 4dc817890b1bbf7c4a27bc8eeda5a333412c9a3c Mon Sep 17 00:00:00 2001 From: hiker Date: Fri, 10 Oct 2014 23:50:27 +1100 Subject: [PATCH 05/15] Reverted 77bd4140a803088231191925e10e4a58e44e0828 (which caused crash and other sfx to be played only once). --- src/karts/kart.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index a5a69d2be..3e8112ced 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1893,12 +1893,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() != SFXManager::SFX_PLAYING) m_boing_sound->play(); } else { - if(!m_crash_sound->isPlaying()) + if(m_crash_sound->getStatus() != SFXManager::SFX_PLAYING) m_crash_sound->play(); } } @@ -1973,7 +1973,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(); } From 216575a7328808bc5661633953a377798880b5a1 Mon Sep 17 00:00:00 2001 From: hiker Date: Sat, 11 Oct 2014 11:55:02 +1100 Subject: [PATCH 06/15] Started to let all sfx related command be executed from the sfx manager to avoid race condition and crashes. --- src/audio/sfx_manager.cpp | 54 ++++++++++++++++++++++++--------------- src/audio/sfx_manager.hpp | 33 ++++++++++++++++++++++-- src/audio/sfx_openal.cpp | 2 +- 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 1bfd2c54e..7ebc2c061 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -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 @@ -163,15 +163,17 @@ SFXManager::~SFXManager() * separate thread. * \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; - m_sfx_to_play.lock(); - m_sfx_to_play.getData().push_back(sfx); - m_sfx_to_play.unlock(); + SFXCommand *sfx_command = new SFXCommand(command, sfx); + + m_sfx_commands.lock(); + m_sfx_commands.getData().push_back(sfx_command); + m_sfx_commands.unlock(); // Wake up the sfx thread pthread_cond_signal(&m_cond_request); @@ -183,7 +185,7 @@ void SFXManager::queue(SFXBase *sfx) */ void SFXManager::stopThread() { - queue(NULL); + queue(SFX_EXIT, NULL); } // stopThread //---------------------------------------------------------------------------- @@ -198,35 +200,47 @@ 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; + 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 diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 4af8f6e22..90e0ce323 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -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,18 @@ private: public: + /** The various commands to be executed by the sfx manager thread + * for each sfx. */ + enum SFXCommands + { + SFX_PLAY = 1, + SFX_STOP = 2, + SFX_PAUSE = 3, + SFX_RESUME = 4, + SFX_DELETE = 5, + SFX_EXIT = 6, + }; // SFXCommands + /** * Entries for custom SFX sounds. These are unique for each kart. * eg. kart->playCustomSFX(SFX_MANAGER::CUSTOM_HORN) @@ -85,6 +98,22 @@ public: 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: + SFXBase *m_sfx; + SFXCommands m_command; + SFXCommand(SFXCommands command, SFXBase *base) + { + m_command = command; + m_sfx = base; + } + }; // SFXCommand + /** Listener position */ Vec3 m_position; @@ -96,7 +125,7 @@ private: std::vector m_all_sfx; /** The list of sound effects to be played in the next update. */ - Synchronised< std::vector > m_sfx_to_play; + Synchronised< std::vector > m_sfx_commands; /** To play non-positional sounds without having to create a new object for each */ std::map m_quick_sounds; @@ -124,7 +153,7 @@ private: public: static void create(); static void destroy(); - void queue(SFXBase *sfx); + void queue(SFXCommands command, SFXBase *sfx); // ------------------------------------------------------------------------ /** Static function to get the singleton sfx manager. */ static SFXManager *get() diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index bb220d7c5..029f1d9f1 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -234,7 +234,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 //----------------------------------------------------------------------------- From bfe84612fa408b070801ba3cd23054592307ec68 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 13 Oct 2014 08:26:45 +1100 Subject: [PATCH 07/15] Let all SFX commands be handled by the sfx manager thread (otherwise events could be handled in the wrong order, e.g. a delete from the main thread before the play in the manager thread, resulting in a crash). Should fix #1511 and #1604. --- src/audio/dummy_sfx.hpp | 5 ++ src/audio/sfx_base.hpp | 4 ++ src/audio/sfx_manager.cpp | 71 +++++++++++++++------- src/audio/sfx_manager.hpp | 4 +- src/audio/sfx_openal.cpp | 45 ++++++++++++-- src/audio/sfx_openal.hpp | 4 ++ src/graphics/hit_sfx.cpp | 5 +- src/graphics/weather.cpp | 6 +- src/items/attachment.cpp | 14 ++--- src/items/bowling.cpp | 6 +- src/items/powerup.cpp | 4 +- src/items/rubber_ball.cpp | 2 +- src/items/swatter.cpp | 2 +- src/karts/controller/player_controller.cpp | 10 +-- src/karts/kart.cpp | 31 +++++----- src/modes/linear_world.cpp | 2 +- src/modes/soccer_world.cpp | 2 +- src/modes/world_status.cpp | 6 +- src/tracks/track_object_presentation.cpp | 44 +++++++++----- 19 files changed, 175 insertions(+), 92 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index 012a75d00..adf73d184 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -40,9 +40,14 @@ public: virtual void position(const Vec3 &position) {} virtual void setLoop(bool status) {} 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 speed(float factor) {} virtual void volume(float gain) {} virtual SFXManager::SFXStatus getStatus() { return SFXManager::SFX_STOPPED; } diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index 65809307b..3ade04eb8 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -52,8 +52,12 @@ public: 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 speed(float factor) = 0; virtual void volume(float gain) = 0; virtual void setMasterVolume(float gain) = 0; diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 7ebc2c061..968adc5d9 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -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::iterator i = m_quick_sounds.begin(); @@ -226,7 +228,15 @@ void* SFXManager::mainLoop(void *obj) me->m_sfx_commands.unlock(); 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_PAUSE: current->m_sfx->reallyPauseNow(); break; + case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; + case SFX_DELETE: { + current->m_sfx->reallyStopNow(); + me->deleteSFX(current->m_sfx); + break; + } default: assert("Not yet supported."); } delete current; @@ -262,12 +272,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; nonSoundEnabledBack(); + m_all_sfx.getData()[n]->onSoundEnabledBack(); } + m_all_sfx.unlock(); } else { @@ -451,7 +462,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 @@ -511,21 +529,26 @@ void SFXManager::deleteSFXMapping(const std::string &name) */ void SFXManager::deleteSFX(SFXBase *sfx) { - if(sfx) sfx->stop(); + if(sfx) sfx->reallyStopNow(); std::vector::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 //---------------------------------------------------------------------------- @@ -535,11 +558,13 @@ void SFXManager::deleteSFX(SFXBase *sfx) */ void SFXManager::pauseAll() { - for (std::vector::iterator i=m_all_sfx.begin(); - i!=m_all_sfx.end(); i++) + m_all_sfx.lock(); + for (std::vector::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 //---------------------------------------------------------------------------- @@ -551,13 +576,15 @@ void SFXManager::resumeAll() // ignore unpausing if sound is disabled if (!sfxAllowed()) return; - for (std::vector::iterator i=m_all_sfx.begin(); - i!=m_all_sfx.end(); i++) + m_all_sfx.lock(); + for (std::vector::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(); } // for i in m_all_sfx + m_all_sfx.unlock(); } // resumeAll //----------------------------------------------------------------------------- @@ -594,11 +621,13 @@ void SFXManager::setMasterSFXVolume(float gain) // regular SFX { - for (std::vector::iterator i=m_all_sfx.begin(); - i!=m_all_sfx.end(); i++) + m_all_sfx.lock(); + for (std::vector::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 diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 90e0ce323..00ca9375e 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -122,7 +122,7 @@ private: std::map m_all_sfx_types; /** The actual instances (sound sources) */ - std::vector m_all_sfx; + Synchronised > m_all_sfx; /** The list of sound effects to be played in the next update. */ Synchronised< std::vector > m_sfx_commands; @@ -150,6 +150,7 @@ private: virtual ~SFXManager(); static void* mainLoop(void *obj); + void deleteSFX(SFXBase *sfx); public: static void create(); static void destroy(); @@ -182,7 +183,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(); diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 029f1d9f1..c596ac55b 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -182,9 +182,16 @@ void SFXOpenAL::setLoop(bool status) } // loop //----------------------------------------------------------------------------- -/** Stops playing this sound effect. +/** Queues a stop for this effect to the sound manager. */ void SFXOpenAL::stop() +{ + SFXManager::get()->queue(SFXManager::SFX_STOP, this); +} // stop +//----------------------------------------------------------------------------- +/** The sfx manager thread executes a stop for this sfx. + */ +void SFXOpenAL::reallyStopNow() { if(!m_ok) return; @@ -193,23 +200,39 @@ void SFXOpenAL::stop() alSourcei(m_soundSource, AL_LOOPING, AL_FALSE); alSourceStop(m_soundSource); 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); 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) { @@ -222,7 +245,17 @@ void SFXOpenAL::resume() alSourcePlay(m_soundSource); SFXManager::checkError("resuming"); -} // resume +} // 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 diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 807111a33..0de11c78a 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -77,8 +77,12 @@ public: 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 speed(float factor); virtual void position(const Vec3 &position); virtual void volume(float gain); diff --git a/src/graphics/hit_sfx.cpp b/src/graphics/hit_sfx.cpp index 53800b28c..507ce3cee 100644 --- a/src/graphics/hit_sfx.cpp +++ b/src/graphics/hit_sfx.cpp @@ -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 //----------------------------------------------------------------------------- diff --git a/src/graphics/weather.cpp b/src/graphics/weather.cpp index 79f51b983..8162f8f11 100644 --- a/src/graphics/weather.cpp +++ b/src/graphics/weather.cpp @@ -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 // ---------------------------------------------------------------------------- diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index ec6816354..02513b4a4 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -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,7 +139,7 @@ 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()); @@ -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; } @@ -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,7 +472,7 @@ 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->play(); diff --git a/src/items/bowling.cpp b/src/items/bowling.cpp index ae0d821d7..28b239e47 100644 --- a/src/items/bowling.cpp +++ b/src/items/bowling.cpp @@ -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 // ----------------------------------------------------------------------------- diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index 6752edc56..9cdbcd8b0 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -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; } diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index 566e69e53..8f9309517 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -109,7 +109,7 @@ RubberBall::~RubberBall() { if(m_ping_sfx->getStatus()==SFXManager::SFX_PLAYING) m_ping_sfx->stop(); - SFXManager::get()->deleteSFX(m_ping_sfx); + m_ping_sfx->deleteSFX(); } // ~RubberBall // ---------------------------------------------------------------------------- diff --git a/src/items/swatter.cpp b/src/items/swatter.cpp index 78a44cc7a..60513aba3 100644 --- a/src/items/swatter.cpp +++ b/src/items/swatter.cpp @@ -100,7 +100,7 @@ Swatter::~Swatter() } if (m_swat_sound) { - SFXManager::get()->deleteSFX(m_swat_sound); + m_swat_sound->deleteSFX(); } } // ~Swatter diff --git a/src/karts/controller/player_controller.cpp b/src/karts/controller/player_controller.cpp index 61298f308..a7a1a3403 100644 --- a/src/karts/controller/player_controller.cpp +++ b/src/karts/controller/player_controller.cpp @@ -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 //----------------------------------------------------------------------------- diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 3e8112ced..4c0430c74 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -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(); @@ -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) @@ -1467,7 +1466,7 @@ void Kart::handleMaterialSFX(const Material *material) // 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; } @@ -1592,7 +1591,7 @@ void Kart::handleMaterialGFX() (m_terrain_sound == NULL || m_terrain_sound->getStatus() == SFXManager::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); diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index 9cbd969d2..8883d0aec 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -73,7 +73,7 @@ void LinearWorld::init() */ LinearWorld::~LinearWorld() { - SFXManager::get()->deleteSFX(m_last_lap_sfx); + m_last_lap_sfx->deleteSFX(); } // ~LinearWorld //----------------------------------------------------------------------------- diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index c853570fe..672411ac3 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -60,7 +60,7 @@ SoccerWorld::SoccerWorld() : WorldWithRank() */ SoccerWorld::~SoccerWorld() { - SFXManager::get()->deleteSFX(m_goal_sound); + m_goal_sound->deleteSFX(); } // ~SoccerWorld //----------------------------------------------------------------------------- diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index 1deeb3903..62419091e 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -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()) diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index c6ba494f2..7b7f7af29 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -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 @@ -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) @@ -451,16 +453,18 @@ void TrackObjectPresentationSound::update(float dt) // moved m_sound->position(m_xyz); } -} +} // update +// ---------------------------------------------------------------------------- void TrackObjectPresentationSound::onTriggerItemApproached(Item* who) { if (m_sound != NULL && m_sound->getStatus() != SFXManager::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); -} +} // 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; From 2b90cb2a69d5bc4464c46b4a1347583b606f73d0 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sun, 12 Oct 2014 20:12:40 -0400 Subject: [PATCH 08/15] Use case-insensitive comparison for animated textures, for some reason --- src/tracks/track.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 076458a5b..1319d4084 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -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; igetMaterialCount(); 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 Date: Mon, 13 Oct 2014 22:04:46 +1100 Subject: [PATCH 09/15] Removed status check when queueing sfx, to get more consistent runtime behaviour. --- src/audio/sfx_manager.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 968adc5d9..9842e687f 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -167,10 +167,6 @@ SFXManager::~SFXManager() */ 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); m_sfx_commands.lock(); @@ -255,7 +251,7 @@ void* SFXManager::mainLoop(void *obj) } // 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. */ From 5cf7b0dca9575f0247efb7ac6ce07b85e05820cd Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 13 Oct 2014 22:06:05 +1100 Subject: [PATCH 10/15] Added computation of the duration of a sound buffer (unused atm). --- src/audio/sfx_buffer.cpp | 54 ++++++++++++++++++++++++------- src/audio/sfx_buffer.hpp | 70 ++++++++++++++++++++++++---------------- 2 files changed, 86 insertions(+), 38 deletions(-) diff --git a/src/audio/sfx_buffer.cpp b/src/audio/sfx_buffer.cpp index 910b29f88..0ac37f2d2 100644 --- a/src/audio/sfx_buffer.cpp +++ b/src/audio/sfx_buffer.cpp @@ -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 diff --git a/src/audio/sfx_buffer.hpp b/src/audio/sfx_buffer.hpp index 98ffbc8e4..e0583b67c 100644 --- a/src/audio/sfx_buffer.hpp +++ b/src/audio/sfx_buffer.hpp @@ -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 From 665f14692381aa198396cbec95f9a31505095b0b Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 14 Oct 2014 08:05:04 +1100 Subject: [PATCH 11/15] Moved SFXStatus enum to SFXBase. --- src/audio/dummy_sfx.hpp | 3 +- src/audio/sfx_base.hpp | 11 ++- src/audio/sfx_manager.cpp | 8 +- src/audio/sfx_manager.hpp | 7 -- src/audio/sfx_openal.cpp | 109 +++++++++++---------- src/audio/sfx_openal.hpp | 13 ++- src/graphics/hit_sfx.cpp | 6 +- src/graphics/material.cpp | 4 +- src/items/bowling.cpp | 2 +- src/items/rubber_ball.cpp | 4 +- src/karts/controller/player_controller.cpp | 2 +- src/karts/kart.cpp | 13 +-- src/modes/linear_world.cpp | 2 +- src/modes/soccer_world.cpp | 2 +- src/modes/world_status.cpp | 2 +- src/states_screens/race_result_gui.cpp | 4 +- src/tracks/track_object_presentation.cpp | 2 +- 17 files changed, 100 insertions(+), 94 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index adf73d184..a14accbf7 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -23,7 +23,6 @@ #include "audio/sfx_base.hpp" - /** * \brief Dummy sound when ogg or openal aren't available * \ingroup audio @@ -50,7 +49,7 @@ public: virtual void deleteSFX() { delete this; } virtual void speed(float factor) {} virtual void volume(float gain) {} - virtual SFXManager::SFXStatus getStatus() { return SFXManager::SFX_STOPPED; } + virtual SFXStatus getStatus() { return SFX_STOPPED; } virtual void onSoundEnabledBack() {} virtual void setRolloff(float rolloff) {} virtual bool isPlaying() { return false; } diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index 3ade04eb8..7fa948390 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -42,6 +42,13 @@ 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 */ @@ -64,9 +71,9 @@ public: virtual void onSoundEnabledBack() = 0; virtual void setRolloff(float rolloff) = 0; virtual const SFXBuffer* getBuffer() const = 0; - virtual SFXManager::SFXStatus getStatus() = 0; + virtual SFXStatus getStatus() = 0; -}; // SfxBase +}; // SFXBase #endif // HEADER_SFX_HPP diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 9842e687f..4d64e9919 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -167,6 +167,10 @@ SFXManager::~SFXManager() */ 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()==SFXBase::SFX_UNKNOWN) return; + SFXCommand *sfx_command = new SFXCommand(command, sfx); m_sfx_commands.lock(); @@ -576,9 +580,7 @@ void SFXManager::resumeAll() for (std::vector::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 diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 00ca9375e..f559407d4 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -89,13 +89,6 @@ 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 diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index c596ac55b..2497b1056 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -40,16 +40,16 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBuffer) : 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_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; // Don't initialise anything else if the sfx manager was not correctly // initialised. First of all the initialisation will not work, and it @@ -66,13 +66,13 @@ SFXOpenAL::~SFXOpenAL() { if (m_ok) { - alDeleteSources(1, &m_soundSource); + alDeleteSources(1, &m_sound_source); } - if (m_owns_buffer && m_soundBuffer != NULL) + if (m_owns_buffer && m_sound_buffer != NULL) { - m_soundBuffer->unload(); - delete m_soundBuffer; + m_sound_buffer->unload(); + delete m_sound_buffer; } } // ~SFXOpenAL @@ -80,40 +80,40 @@ 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"); + // m_sound_buffer, 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"); @@ -137,7 +137,7 @@ void SFXOpenAL::speed(float factor) { factor = 0.5f; } - alSourcef(m_soundSource,AL_PITCH,factor); + alSourcef(m_sound_source,AL_PITCH,factor); SFXManager::checkError("changing the speed"); } // speed @@ -151,7 +151,7 @@ void SFXOpenAL::volume(float gain) if(!m_ok) 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"); } // volume @@ -163,7 +163,7 @@ void SFXOpenAL::setMasterVolume(float gain) if(!m_ok) 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 @@ -177,7 +177,7 @@ void SFXOpenAL::setLoop(bool status) if(!m_ok) 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 @@ -197,8 +197,8 @@ void SFXOpenAL::reallyStopNow() m_is_playing = false; 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"); } // reallyStopNow @@ -217,7 +217,7 @@ void SFXOpenAL::pause() void SFXOpenAL::reallyPauseNow() { if(!m_ok) return; - alSourcePause(m_soundSource); + alSourcePause(m_sound_source); SFXManager::checkError("pausing"); } // reallyPauseNow @@ -243,7 +243,8 @@ void SFXOpenAL::reallyResumeNow() if (!m_ok) return; } - alSourcePlay(m_soundSource); + if(getStatus()==SFX_PAUSED) + alSourcePlay(m_sound_source); SFXManager::checkError("resuming"); } // reallyResumeNow @@ -285,7 +286,7 @@ void SFXOpenAL::reallyPlayNow() if (!m_ok) return; } - alSourcePlay(m_soundSource); + alSourcePlay(m_sound_source); SFXManager::checkError("playing"); } // reallyPlayNow @@ -307,7 +308,7 @@ void SFXOpenAL::position(const Vec3 &position) return; if (!m_ok) { - 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) @@ -322,16 +323,16 @@ 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"); @@ -340,19 +341,19 @@ void SFXOpenAL::position(const Vec3 &position) //----------------------------------------------------------------------------- /** Returns the status of this sound effect. */ -SFXManager::SFXStatus SFXOpenAL::getStatus() +SFXBase::SFXStatus SFXOpenAL::getStatus() { - if(!m_ok) return SFXManager::SFX_UNKNOWN; + if(!m_ok) return SFX_UNKNOWN; int state = 0; - alGetSourcei(m_soundSource, AL_SOURCE_STATE, &state); + alGetSourcei(m_sound_source, 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; + case AL_STOPPED: return SFX_STOPPED; + case AL_PLAYING: return SFX_PLAYING; + case AL_PAUSED: return SFX_PAUSED; + case AL_INITIAL: return SFX_INITIAL; + default: return SFX_UNKNOWN; } } // getStatus @@ -365,10 +366,10 @@ void SFXOpenAL::onSoundEnabledBack() if (!m_ok) init(); if (m_ok) { - 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); } } } @@ -377,7 +378,7 @@ void SFXOpenAL::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 diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 0de11c78a..8b63fc41a 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -28,7 +28,6 @@ # include #endif #include "audio/sfx_base.hpp" -#include "audio/sfx_manager.hpp" #include "utils/leak_check.hpp" /** @@ -38,8 +37,12 @@ class SFXOpenAL : public SFXBase { private: - SFXBuffer* m_soundBuffer; //!< Buffers hold sound data. - ALuint m_soundSource; //!< Sources are points emitting sound. + /** Buffers hold sound data. */ + SFXBuffer* m_sound_buffer; + + /** Sources are points emitting sound. */ + ALuint m_sound_source; + bool m_ok; bool m_positional; float m_defaultGain; @@ -87,11 +90,11 @@ public: virtual void position(const Vec3 &position); virtual void volume(float gain); virtual void setMasterVolume(float gain); - virtual SFXManager::SFXStatus getStatus(); + virtual SFXStatus getStatus(); virtual void onSoundEnabledBack(); virtual void setRolloff(float rolloff); - virtual const SFXBuffer* getBuffer() const { return m_soundBuffer; } + virtual const SFXBuffer* getBuffer() const { return m_sound_buffer; } LEAK_CHECK() diff --git a/src/graphics/hit_sfx.cpp b/src/graphics/hit_sfx.cpp index 507ce3cee..391d7118a 100644 --- a/src/graphics/hit_sfx.cpp +++ b/src/graphics/hit_sfx.cpp @@ -64,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 diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index b9244c1a6..725c0908c 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -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 (speedplay(); } - else if (sfx->getStatus() == SFXManager::SFX_PLAYING) + else if (sfx->getStatus() == SFXBase::SFX_PLAYING) { if (speedgetStatus()==SFXManager::SFX_PLAYING) + if (m_roll_sfx->getStatus()==SFXBase::SFX_PLAYING) m_roll_sfx->position(getXYZ()); return false; diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index 8f9309517..f3b6b5f19 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -107,7 +107,7 @@ 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(); m_ping_sfx->deleteSFX(); } // ~RubberBall @@ -541,7 +541,7 @@ 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->play(); diff --git a/src/karts/controller/player_controller.cpp b/src/karts/controller/player_controller.cpp index a7a1a3403..d4a6e47eb 100644 --- a/src/karts/controller/player_controller.cpp +++ b/src/karts/controller/player_controller.cpp @@ -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(); diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 4c0430c74..b3daca52c 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1079,6 +1079,7 @@ void Kart::eliminate() */ void Kart::update(float dt) { + Log::verbose("sfx", "%s crash state %d", getIdent().c_str(), m_crash_sound->getStatus()); if ( UserConfigParams::m_graphical_effects ) { // update star effect (call will do nothing if stars are not activated) @@ -1461,7 +1462,7 @@ 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 @@ -1477,8 +1478,8 @@ 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()); material->setSFXSpeed(m_terrain_sound, m_speed, m_schedule_pause); @@ -1589,7 +1590,7 @@ void Kart::handleMaterialGFX() const std::string &s = surface_material->getSFXName(); if (s != "" && !dynamic_cast(getKartAnimation())&& (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(); m_previous_terrain_sound = m_terrain_sound; @@ -1892,12 +1893,12 @@ void Kart::crashed(const Material* m, AbstractKart *k) // it's not already playing. 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(); } else { - if(m_crash_sound->getStatus() != SFXManager::SFX_PLAYING) + if(m_crash_sound->getStatus() != SFXBase::SFX_PLAYING) m_crash_sound->play(); } } diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index 8883d0aec..03086a353 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -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(); diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 672411ac3..022ffc9f0 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -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(); } diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index 62419091e..a969e7efd 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -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; diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 6dc363416..86a25afd3 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -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 { diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 7b7f7af29..3ef6c8d56 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -458,7 +458,7 @@ void TrackObjectPresentationSound::update(float dt) // ---------------------------------------------------------------------------- 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(); } From d753fab7dba3710c989d82a507ba0497fa7e1e06 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 14 Oct 2014 09:01:13 +1100 Subject: [PATCH 12/15] Removed debug output. --- src/karts/kart.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index b3daca52c..fd66b8ebc 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -1079,7 +1079,6 @@ void Kart::eliminate() */ void Kart::update(float dt) { - Log::verbose("sfx", "%s crash state %d", getIdent().c_str(), m_crash_sound->getStatus()); if ( UserConfigParams::m_graphical_effects ) { // update star effect (call will do nothing if stars are not activated) From 22633aa363039d655cf2b9c5760768b43002dae7 Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 14 Oct 2014 09:01:26 +1100 Subject: [PATCH 13/15] Avoid calling querying the openal status in getStatus (which causes a slowdown of sfx). --- src/audio/sfx_manager.cpp | 1 + src/audio/sfx_openal.cpp | 107 +++++++++++++++++++++----------------- src/audio/sfx_openal.hpp | 61 ++++++++++++---------- 3 files changed, 93 insertions(+), 76 deletions(-) diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 4d64e9919..a10b3b474 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -589,6 +589,7 @@ void SFXManager::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) { diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 2497b1056..a29d3ab44 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -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 #include -SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBuffer) : SFXBase() +SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool owns_buffer) : SFXBase() { m_sound_buffer = buffer; m_sound_source = 0; - m_ok = false; + 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 = ownsBuffer; + 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,15 +61,16 @@ 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_sound_source); } - if (m_owns_buffer && m_sound_buffer != NULL) + if (m_owns_buffer && m_sound_buffer) { m_sound_buffer->unload(); delete m_sound_buffer; @@ -86,9 +87,6 @@ bool SFXOpenAL::init() 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_sound_buffer, rolloff, m_defaultGain, positional ? "true" : "false"); - alSourcei (m_sound_source, AL_BUFFER, m_sound_buffer->getBufferID()); if (!SFXManager::checkError("attaching the buffer to the source")) @@ -115,18 +113,35 @@ bool SFXOpenAL::init() 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. * \param factor Speedup/slowdown between 0.5 and 2.0 */ void SFXOpenAL::speed(float factor) { - if(!m_ok || isnan(factor)) return; + if(m_status==SFX_UNKNOWN || isnan(factor)) return; //OpenAL only accepts pitches in the range of 0.5 to 2.0 if(factor > 2.0f) @@ -149,7 +164,7 @@ void SFXOpenAL::volume(float gain) { m_gain = m_defaultGain * gain; - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain); SFXManager::checkError("setting volume"); @@ -161,7 +176,7 @@ void SFXOpenAL::setMasterVolume(float gain) { m_master_gain = gain; - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); @@ -175,7 +190,7 @@ void SFXOpenAL::setLoop(bool status) { m_loop = status; - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE); SFXManager::checkError("looping"); @@ -193,9 +208,10 @@ void SFXOpenAL::stop() */ void SFXOpenAL::reallyStopNow() { - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; m_is_playing = false; + m_status = SFX_STOPPED; m_loop = false; alSourcei(m_sound_source, AL_LOOPING, AL_FALSE); alSourceStop(m_sound_source); @@ -216,7 +232,8 @@ void SFXOpenAL::pause() */ void SFXOpenAL::reallyPauseNow() { - if(!m_ok) return; + if(m_status==SFX_UNKNOWN) return; + m_status = SFX_PAUSED; alSourcePause(m_sound_source); SFXManager::checkError("pausing"); } // reallyPauseNow @@ -234,18 +251,21 @@ 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; } - if(getStatus()==SFX_PAUSED) + if(m_status==SFX_PAUSED) + { alSourcePlay(m_sound_source); - SFXManager::checkError("resuming"); + SFXManager::checkError("resuming"); + m_status = SFX_PLAYING; + } } // reallyResumeNow //----------------------------------------------------------------------------- @@ -277,17 +297,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_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 //----------------------------------------------------------------------------- @@ -306,9 +333,10 @@ void SFXOpenAL::position(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_sound_buffer->getFileName().c_str()); + Log::warn("SFX", "Position called on non-ok SFX <%s>", + m_sound_buffer->getFileName().c_str()); return; } if (!m_positional) @@ -338,33 +366,14 @@ void SFXOpenAL::position(const Vec3 &position) SFXManager::checkError("positioning"); } // position -//----------------------------------------------------------------------------- -/** Returns the status of this sound effect. - */ -SFXBase::SFXStatus SFXOpenAL::getStatus() -{ - if(!m_ok) return SFX_UNKNOWN; - - int state = 0; - alGetSourcei(m_sound_source, AL_SOURCE_STATE, &state); - switch(state) - { - case AL_STOPPED: return SFX_STOPPED; - case AL_PLAYING: return SFX_PLAYING; - case AL_PAUSED: return SFX_PAUSED; - case AL_INITIAL: return SFX_INITIAL; - default: return SFX_UNKNOWN; - } -} // getStatus - //----------------------------------------------------------------------------- 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_sound_source, AL_GAIN, 0); play(); @@ -372,7 +381,7 @@ void SFXOpenAL::onSoundEnabledBack() alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain); } } -} +} // onSoundEnabledBack //----------------------------------------------------------------------------- diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index 8b63fc41a..cc975e192 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -37,13 +37,17 @@ class SFXOpenAL : public SFXBase { private: + LEAK_CHECK() + /** Buffers hold sound data. */ SFXBuffer* m_sound_buffer; /** Sources are points emitting sound. */ ALuint m_sound_source; - bool m_ok; + /** The status of this SFX. */ + SFXStatus m_status; + bool m_positional; float m_defaultGain; @@ -65,39 +69,42 @@ 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 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 speed(float factor); - virtual void position(const Vec3 &position); - virtual void volume(float gain); - virtual void setMasterVolume(float gain); - virtual SFXStatus getStatus(); - virtual void onSoundEnabledBack(); - virtual void setRolloff(float rolloff); + 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 speed(float factor); + virtual void position(const Vec3 &position); + virtual void volume(float gain); + virtual void setMasterVolume(float gain); + virtual void onSoundEnabledBack(); + virtual void setRolloff(float rolloff); + virtual SFXStatus getStatus(); + // ------------------------------------------------------------------------ + /** Returns the buffer associated with this sfx. */ virtual const SFXBuffer* getBuffer() const { return m_sound_buffer; } - LEAK_CHECK() - }; // SFXOpenAL #endif From c18579d86a67414051d5b56dd7f85d34520c944c Mon Sep 17 00:00:00 2001 From: hiker Date: Tue, 14 Oct 2014 09:57:53 +1100 Subject: [PATCH 14/15] Fixed compiler warning. --- src/physics/btKart.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/physics/btKart.cpp b/src/physics/btKart.cpp index c1f3bf3f5..503f22f0c 100644 --- a/src/physics/btKart.cpp +++ b/src/physics/btKart.cpp @@ -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); From 8fcc373b2a2abab27135a9956213e423896bfadd Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 15 Oct 2014 07:55:18 +1100 Subject: [PATCH 15/15] Add volume, speed, and position settings to be done by the sfx thread. Removed more unnecessary error checks (which mostly flood stdout with 'not playing ...' messages), and renamed volume, position and speed to setVolume, setPosition and setSpeed. --- src/audio/dummy_sfx.hpp | 39 ++++++------ src/audio/sfx_base.hpp | 43 +++++++------ src/audio/sfx_manager.cpp | 67 ++++++++++++++++----- src/audio/sfx_manager.hpp | 45 +++++++++++--- src/audio/sfx_openal.cpp | 51 +++++++++++++--- src/audio/sfx_openal.hpp | 9 ++- src/graphics/hit_sfx.cpp | 6 +- src/graphics/material.cpp | 4 +- src/items/attachment.cpp | 6 +- src/items/bowling.cpp | 2 +- src/items/powerup.cpp | 26 ++++---- src/items/rubber_ball.cpp | 2 +- src/items/swatter.cpp | 2 +- src/karts/kart.cpp | 48 +++++++-------- src/states_screens/options_screen_audio.cpp | 2 +- src/tracks/track_object_presentation.cpp | 6 +- 16 files changed, 230 insertions(+), 128 deletions(-) diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index a14accbf7..8f5572431 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -36,24 +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 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 speed(float factor) {} - virtual void volume(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; } + 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 diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index 7fa948390..a23ef0dbb 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -52,26 +52,29 @@ public: 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 reallyStopNow() = 0; - virtual void pause() = 0; - virtual void reallyPauseNow() = 0; - virtual void resume() = 0; - virtual void reallyResumeNow() = 0; - virtual void deleteSFX() = 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 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 diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index a10b3b474..288e80c85 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -160,26 +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(SFXCommands command, SFXBase *sfx) { - // Don't add sfx that are either not working correctly (e.g. because sfx - // are disabled); - if(sfx && sfx->getStatus()==SFXBase::SFX_UNKNOWN) return; - 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.getData().push_back(sfx_command); + 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 @@ -228,10 +261,16 @@ void* SFXManager::mainLoop(void *obj) 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_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); diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index f559407d4..8f9edc25b 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -62,12 +62,15 @@ public: * for each sfx. */ enum SFXCommands { - SFX_PLAY = 1, - SFX_STOP = 2, - SFX_PAUSE = 3, - SFX_RESUME = 4, - SFX_DELETE = 5, - SFX_EXIT = 6, + SFX_PLAY = 1, + SFX_STOP, + SFX_PAUSE, + SFX_RESUME, + SFX_DELETE, + SFX_SPEED, + SFX_POSITION, + SFX_VOLUME, + SFX_EXIT, }; // SFXCommands /** @@ -98,15 +101,34 @@ private: 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; - } + 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; @@ -144,10 +166,13 @@ private: static void* mainLoop(void *obj); void deleteSFX(SFXBase *sfx); + void queueCommand(SFXCommand *command); public: static void create(); static void destroy(); 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() diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index a29d3ab44..5494222c9 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -136,13 +136,23 @@ SFXBase::SFXStatus SFXOpenAL::getStatus() } // 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_status==SFX_UNKNOWN || 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) { @@ -153,22 +163,32 @@ void SFXOpenAL::speed(float factor) factor = 0.5f; } alSourcef(m_sound_source,AL_PITCH,factor); - SFXManager::checkError("changing the speed"); -} // speed +} // 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_status==SFX_UNKNOWN) return; alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain); - SFXManager::checkError("setting volume"); -} // volume +} // reallySetVolume //----------------------------------------------------------------------------- @@ -329,7 +349,18 @@ 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; @@ -364,7 +395,7 @@ void SFXOpenAL::position(const Vec3 &position) } SFXManager::checkError("positioning"); -} // position +} // reallySetPosition //----------------------------------------------------------------------------- diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index cc975e192..a4b59b587 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -93,9 +93,12 @@ public: 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 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); diff --git a/src/graphics/hit_sfx.cpp b/src/graphics/hit_sfx.cpp index 391d7118a..e9018a474 100644 --- a/src/graphics/hit_sfx.cpp +++ b/src/graphics/hit_sfx.cpp @@ -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 @@ -53,7 +53,7 @@ HitSFX::~HitSFX() void HitSFX::setPlayerKartHit() { if(race_manager->getNumLocalPlayers()) - m_sfx->volume(1.0f); + m_sfx->setVolume(1.0f); } // setPlayerKartHit //----------------------------------------------------------------------------- diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 725c0908c..7a4ddca5f 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -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 //----------------------------------------------------------------------------- diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index 02513b4a4..3974ed3f2 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -142,7 +142,7 @@ void Attachment::set(AttachmentType type, float time, 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: @@ -439,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 @@ -474,7 +474,7 @@ void Attachment::update(float dt) m_time_left = 0.0f; 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 diff --git a/src/items/bowling.cpp b/src/items/bowling.cpp index 7ac248ee4..4d0b8c935 100644 --- a/src/items/bowling.cpp +++ b/src/items/bowling.cpp @@ -173,7 +173,7 @@ bool Bowling::updateAndDelete(float dt) } if (m_roll_sfx->getStatus()==SFXBase::SFX_PLAYING) - m_roll_sfx->position(getXYZ()); + m_roll_sfx->setPosition(getXYZ()); return false; } // updateAndDelete diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index 9cdbcd8b0..22652271a 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -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; diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index f3b6b5f19..b9ca9a3f7 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -543,7 +543,7 @@ float RubberBall::updateHeight() m_height_timer -= m_interval; if(m_ping_sfx->getStatus()!=SFXBase::SFX_PLAYING) { - m_ping_sfx->position(getXYZ()); + m_ping_sfx->setPosition(getXYZ()); m_ping_sfx->play(); } diff --git a/src/items/swatter.cpp b/src/items/swatter.cpp index 60513aba3..baf735112 100644 --- a/src/items/swatter.cpp +++ b/src/items/swatter.cpp @@ -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 diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index fd66b8ebc..d017ba85d 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -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() ); } } @@ -756,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 @@ -928,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); @@ -1184,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 @@ -1447,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 ); } } @@ -1480,7 +1480,7 @@ void Kart::handleMaterialSFX(const Material *material) (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); } @@ -2123,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 //----------------------------------------------------------------------------- diff --git a/src/states_screens/options_screen_audio.cpp b/src/states_screens/options_screen_audio.cpp index b0ac7c419..c3cfc751b 100644 --- a/src/states_screens/options_screen_audio.cpp +++ b/src/states_screens/options_screen_audio.cpp @@ -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; diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 3ef6c8d56..f8367f233 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -427,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); @@ -451,7 +451,7 @@ 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 @@ -495,7 +495,7 @@ void TrackObjectPresentationSound::move(const core::vector3df& xyz, const core::vector3df& scale) { m_xyz = xyz; - if (m_sound != NULL) m_sound->position(xyz); + if (m_sound != NULL) m_sound->setPosition(xyz); } // move // ----------------------------------------------------------------------------