From 4200f316de917ae656fd8339efff605dc17299bd Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 17 Mar 2008 05:18:26 +0000 Subject: [PATCH] Added support for 2 music 'styles' in one .music file: the normal music, and a special 'faster' music which will be played during the last track. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1657 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/game_manager.cpp | 8 +-- src/kart.cpp | 6 +- src/music.hpp | 17 +++-- src/music_information.cpp | 34 +++++---- src/music_information.hpp | 18 +++-- src/music_ogg.cpp | 11 ++- src/music_ogg.hpp | 1 + src/sound_manager.cpp | 148 ++++++++++++++++++++++++++++---------- src/sound_manager.hpp | 32 +++++---- 9 files changed, 190 insertions(+), 85 deletions(-) diff --git a/src/game_manager.cpp b/src/game_manager.cpp index f104182c2..37a2a02d9 100644 --- a/src/game_manager.cpp +++ b/src/game_manager.cpp @@ -70,7 +70,8 @@ void GameManager::run() m_prev_time = m_curr_time; m_curr_time = SDL_GetTicks(); - + float dt = (m_curr_time - m_prev_time ) * 0.001f; + if (!music_on && !race_manager->raceIsActive()) { sound_manager->playMusic(stk_config->m_title_music); @@ -80,8 +81,7 @@ void GameManager::run() if (race_manager->raceIsActive()) { music_on = false; - float dt = (m_curr_time - m_prev_time ) * 0.001f; - if(user_config->m_profile) dt=1.0f/60.0f; + if(user_config->m_profile) dt=1.0f/60.0f; // In the first call dt might be large (includes loading time), // which can cause the camera to significantly tilt scene->draw(world->getPhase()==World::SETUP_PHASE ? 0.0f : dt); @@ -145,7 +145,7 @@ void GameManager::run() } menu_manager->update(); - sound_manager->update(); + sound_manager->update(dt); glFlush(); SDL_GL_SwapBuffers(); diff --git a/src/kart.cpp b/src/kart.cpp index ecd10356e..6d09e82e6 100644 --- a/src/kart.cpp +++ b/src/kart.cpp @@ -439,7 +439,11 @@ void Kart::doLapCounting () setTimeAtLap(world->getTime()); m_race_lap++ ; } - + // Sound manager makes sure that only the first call switches the music + if(m_race_lap==world->m_race_setup.m_num_laps-1) // last lap started + { + sound_manager->switchToFastMusic(); + } // Only do timings if original time was set properly. Driving backwards // over the start line will cause the lap start time to be set to -1. if(m_lap_start_time>=0.0) diff --git a/src/music.hpp b/src/music.hpp index cb89b40cb..08a235a1a 100644 --- a/src/music.hpp +++ b/src/music.hpp @@ -25,16 +25,15 @@ class Music { public: - virtual bool load(const std::string& filename)= 0; + virtual bool load (const std::string& filename) = 0; + virtual bool playMusic () = 0; + virtual bool stopMusic () = 0; + virtual bool pauseMusic () = 0; + virtual bool resumeMusic () = 0; + virtual void updateFading(float percent) = 0; + virtual void update () = 0; - virtual bool playMusic()= 0; - virtual bool stopMusic()= 0; - virtual bool pauseMusic()= 0; - virtual bool resumeMusic()= 0; - - virtual void update()= 0; - - virtual ~Music(){}; + virtual ~Music () {}; }; #endif // HEADER_MUSIC_H diff --git a/src/music_information.cpp b/src/music_information.cpp index 7bfc3e0f2..ebd041602 100755 --- a/src/music_information.cpp +++ b/src/music_information.cpp @@ -34,16 +34,18 @@ MusicInformation::MusicInformation(const std::string& filename) { - m_title = ""; - m_composer = ""; - m_numLoops = LOOP_FOREVER; - + m_title = ""; + m_composer = ""; + m_numLoops = LOOP_FOREVER; + m_normal_filename = ""; + m_fast_filename = ""; + m_fade_time = 1.0f; if(StringUtils::extension(filename)!="music") { // Create information just from ogg file // ------------------------------------- - m_title = StringUtils::without_extension(StringUtils::basename(filename)); - m_ogg_filename = filename; + m_title = StringUtils::without_extension(StringUtils::basename(filename)); + m_normal_filename = filename; return; } @@ -63,15 +65,23 @@ MusicInformation::MusicInformation(const std::string& filename) filename.c_str()); throw std::runtime_error(msg); } - LISP->get ("title", m_title ); - LISP->get ("composer", m_composer ); - LISP->get ("loop", m_numLoops ); - LISP->get ("music", m_ogg_filename); - LISP->getVector("tracks", m_all_tracks); + LISP->get ("title", m_title ); + LISP->get ("composer", m_composer ); + LISP->get ("loop", m_numLoops ); + LISP->get ("music", m_normal_filename); + LISP->get ("fast-music", m_fast_filename ); + LISP->get ("fade-time", m_fade_time ); + LISP->getVector("tracks", m_all_tracks ); // Get the path from the filename and add it to the ogg filename std::string path=StringUtils::path(filename); - m_ogg_filename=path+"/"+m_ogg_filename; + m_normal_filename=path+"/"+m_normal_filename; + + // Get the path from the filename and add it to the ogg filename + if(m_fast_filename!="") + { + m_fast_filename=path+"/"+m_fast_filename; + } delete ROOT; diff --git a/src/music_information.hpp b/src/music_information.hpp index 5a95a2469..a67b55f5e 100755 --- a/src/music_information.hpp +++ b/src/music_information.hpp @@ -28,16 +28,20 @@ class MusicInformation private: std::string m_composer; std::string m_title; - std::string m_ogg_filename; + std::string m_normal_filename; + std::string m_fast_filename; std::vector m_all_tracks; int m_numLoops; + float m_fade_time; static const int LOOP_FOREVER=-1; public: - MusicInformation(const std::string& filename); - const std::string& getComposer () const {return m_composer; } - const std::string& getTitle () const {return m_title; } - const std::string& getFilename () const {return m_ogg_filename; } - int getNumLoops () const {return m_numLoops; } - void addMusicToTracks() const; + MusicInformation (const std::string& filename); + const std::string& getComposer () const {return m_composer; } + const std::string& getTitle () const {return m_title; } + const std::string& getNormalFilename() const {return m_normal_filename; } + const std::string& getFastFilename () const {return m_fast_filename; } + int getNumLoops () const {return m_numLoops; } + float getFadeTime () const {return m_fade_time; } + void addMusicToTracks () const; }; // MusicInformation #endif diff --git a/src/music_ogg.cpp b/src/music_ogg.cpp index fdd255a79..bad2cef25 100644 --- a/src/music_ogg.cpp +++ b/src/music_ogg.cpp @@ -214,6 +214,13 @@ bool MusicOggStream::resumeMusic() return true; } +//----------------------------------------------------------------------------- +void MusicOggStream::updateFading(float percent) +{ + alSourcef(m_soundSource,AL_GAIN,percent); + update(); +} // updateFading + //----------------------------------------------------------------------------- void MusicOggStream::update() { @@ -252,7 +259,7 @@ void MusicOggStream::update() alGetSourcei(m_soundSource, AL_SOURCE_STATE, &state); if (state != AL_PLAYING) { - fprintf(stderr,"WARNING: Alsa source state: %d\n", state); + fprintf(stderr,"WARNING: Alsa source state: %d\n", state); alGetSourcei(m_soundSource, AL_BUFFERS_PROCESSED, &processed); alSourcePlay(m_soundSource); } @@ -260,7 +267,7 @@ void MusicOggStream::update() else { // no more data. Seek to beginning -> loop - ov_time_seek(&m_oggStream, 0); + ov_time_seek(&m_oggStream, 0); } } diff --git a/src/music_ogg.hpp b/src/music_ogg.hpp index adc275fec..945d138cb 100644 --- a/src/music_ogg.hpp +++ b/src/music_ogg.hpp @@ -40,6 +40,7 @@ public: virtual ~MusicOggStream(); virtual void update(); + virtual void updateFading(float percent); virtual bool load(const std::string& filename); diff --git a/src/sound_manager.cpp b/src/sound_manager.cpp index 88871299c..f5d569160 100644 --- a/src/sound_manager.cpp +++ b/src/sound_manager.cpp @@ -45,7 +45,8 @@ SoundManager* sound_manager= NULL; SoundManager::SoundManager() : m_sfxs(NUM_SOUNDS) { - m_current_music = NULL; + m_normal_music = NULL; + m_fast_music = NULL; if(alutInit(0, NULL) == AL_TRUE) // init OpenAL sound system m_initialized = true; @@ -93,10 +94,15 @@ SoundManager::~SoundManager() } m_sfxs.empty(); - if (m_current_music != NULL) + if (m_normal_music != NULL) { - delete m_current_music; - m_current_music = NULL; + delete m_normal_music; + m_normal_music = NULL; + } + if (m_fast_music != NULL) + { + delete m_fast_music; + m_fast_music = NULL; } if(m_initialized) @@ -147,8 +153,8 @@ const MusicInformation* SoundManager::getMusicInformation(const std::string& fil { return NULL; } - const std::string basename=StringUtils::basename(filename); - const MusicInformation* mi=m_allMusic[basename]; + const std::string basename = StringUtils::basename(filename); + const MusicInformation* mi = m_allMusic[basename]; if(!mi) { mi = new MusicInformation(filename); @@ -173,47 +179,75 @@ void SoundManager::playSfx(unsigned int id) void SoundManager::playMusic(const MusicInformation* mi) { m_music_information = mi; + m_time_since_fade = 0.0f; + m_mode = SOUND_NORMAL; if(!user_config->doMusic() || !m_initialized) return; - - if (m_current_music != NULL) + + if (m_normal_music != NULL) { - delete m_current_music; - m_current_music = NULL; + delete m_normal_music; + m_normal_music = NULL; } - if (mi->getFilename()== "") + if (mi->getNormalFilename()== "") // nothing to play { - // nothing to play - return; - } - const std::string& filename=mi->getFilename(); - if (!strcasecmp(".ogg", filename.c_str()+filename.size()-4)) - m_current_music= new MusicOggStream(); - - if(m_current_music == NULL) // no support for file - { - fprintf(stderr, "WARNING: music file %s format not recognized.\n", filename.c_str()); return; } - if((m_current_music->load(filename)) == false) + // First load the 'normal' music + // ----------------------------- + const std::string& filename_normal=mi->getNormalFilename(); + if(StringUtils::extension(filename_normal)!="ogg") { - delete m_current_music; - m_current_music=0; + fprintf(stderr, "WARNING: music file %s format not recognized.\n", + filename_normal.c_str()); + return; + } + m_normal_music= new MusicOggStream(); + + if((m_normal_music->load(filename_normal)) == false) + { + delete m_normal_music; + m_normal_music=0; fprintf(stderr, "WARNING: Unabled to load music %s, not supported or not found.\n", - filename.c_str()); + filename_normal.c_str()); + return; + } + m_normal_music->playMusic(); + + // Then (if available) load the music for the last track + // ----------------------------------------------------- + const std::string& filename_fast=mi->getFastFilename(); + if(StringUtils::extension(filename_fast)!="ogg") + { + fprintf(stderr, + "WARNING: music file %s format not recognized, fast music is ignored\n", + filename_fast.c_str()); + return; + } + m_fast_music= new MusicOggStream(); + + if((m_fast_music->load(filename_fast)) == false) + { + delete m_fast_music; + m_fast_music=0; + fprintf(stderr, "WARNING: Unabled to load fast music %s, not supported or not found.\n", + filename_fast.c_str()); return; } - m_current_music->playMusic(); } // playMusic //----------------------------------------------------------------------------- void SoundManager::stopMusic() { - if (m_current_music != NULL) + if (m_normal_music != NULL) { - m_current_music->stopMusic(); + m_normal_music->stopMusic(); + } + if (m_fast_music != NULL) + { + m_fast_music->stopMusic(); } m_music_information = NULL; } // stopMusic @@ -221,28 +255,68 @@ void SoundManager::stopMusic() //----------------------------------------------------------------------------- void SoundManager::pauseMusic() { - if (m_current_music != NULL) + if (m_normal_music != NULL) { - m_current_music->pauseMusic(); + m_normal_music->pauseMusic(); + } + if (m_fast_music != NULL) + { + m_fast_music->pauseMusic(); } } // pauseMusic //----------------------------------------------------------------------------- +/*** If available select the faster music (usually for the last track). +*/ +void SoundManager::switchToFastMusic() +{ + if(m_fast_music && m_mode==SOUND_NORMAL) + { + m_mode = SOUND_FADING; + m_time_since_fade = 0.0f; + m_fast_music->playMusic(); + } +} // switchToFastMusic +//----------------------------------------------------------------------------- + void SoundManager::resumeMusic() { - if (m_current_music != NULL) + if (m_normal_music != NULL) { - m_current_music->resumeMusic(); + m_normal_music->resumeMusic(); + } + if (m_fast_music != NULL) + { + m_fast_music->resumeMusic(); } } // resumeMusic //----------------------------------------------------------------------------- -void SoundManager::update() +void SoundManager::update(float dt) { - if (m_current_music != NULL) - { - m_current_music->update(); - } + switch(m_mode) + { + case SOUND_FADING: { + m_time_since_fade +=dt; + if(m_time_since_fade>=m_music_information->getFadeTime()) + { + m_mode=SOUND_FAST; + m_normal_music->stopMusic(); + m_fast_music->update(); + return; + } + float fraction=m_time_since_fade/m_music_information->getFadeTime(); + m_normal_music->updateFading(1-fraction); + m_fast_music->updateFading(fraction); + break; + } + case SOUND_NORMAL: + m_normal_music->update(); + break; + case SOUND_FAST: + m_fast_music->update(); + break; + } // switch } // update diff --git a/src/sound_manager.hpp b/src/sound_manager.hpp index 5b5d74885..fa04a0e5f 100644 --- a/src/sound_manager.hpp +++ b/src/sound_manager.hpp @@ -40,33 +40,39 @@ enum enumSFX {SOUND_UGH, SOUND_WINNER, SOUND_CRASH, SOUND_GRAB, class SoundManager { private: + + typedef std::vector SFXsType; + + SFXsType m_sfxs; + Music *m_normal_music, + *m_fast_music; + MusicInformation const *m_music_information; + + bool m_initialized; //If the sound could not be initialized, e.g. + //if the player doesn't has a sound card, we want + //to avoid anything sound related so we crash the game. + std::map + m_allMusic; void loadMusicInformation(); - std::map m_allMusic; + enum {SOUND_NORMAL, SOUND_FADING, + SOUND_FAST} m_mode; + float m_time_since_fade; + public: SoundManager(); virtual ~SoundManager(); - void update(); + void update(float dt); void playSfx(unsigned int id); void playMusic(const MusicInformation* mi); void stopMusic(); void pauseMusic(); void resumeMusic(); + void switchToFastMusic(); const MusicInformation* getCurrentMusic() {return m_music_information; } const MusicInformation* getMusicInformation(const std::string& filename); void loadMusicFromOneDir(const std::string& dir); void addMusicToTracks() const; -private: - - typedef std::vector SFXsType; - - SFXsType m_sfxs; - Music* m_current_music; - MusicInformation const* m_music_information; - - bool m_initialized; //If the sound could not be initialized, for example, - //if the player doesn't has a sound card, we want - //to avoid anything sound related so we crash the game. };