diff --git a/src/game_manager.cpp b/src/game_manager.cpp index 4f39c4fd5..f6b62e55f 100644 --- a/src/game_manager.cpp +++ b/src/game_manager.cpp @@ -91,11 +91,12 @@ void GameManager::run() } dt *= 0.001f; - if (!music_on && !race_manager->raceIsActive()) - { - sound_manager->playMusic(stk_config->m_title_music); + if (!music_on && !race_manager->raceIsActive()) + { + sound_manager->stopMusic(); // stop potential 'left over' music from race + sound_manager->startMusic(stk_config->m_title_music); music_on = true; - } + } if (race_manager->raceIsActive()) { diff --git a/src/gui/config_sound.cpp b/src/gui/config_sound.cpp index 0a6a5a86b..b49fef2d9 100644 --- a/src/gui/config_sound.cpp +++ b/src/gui/config_sound.cpp @@ -88,7 +88,7 @@ void ConfigSound::select() { user_config->setMusic(UserConfig::UC_ENABLE); widget_manager->setWgtText(WTOK_MUSIC, _("Turn off music")); - sound_manager->playMusic(sound_manager->getCurrentMusic()); + sound_manager->startMusic(sound_manager->getCurrentMusic()); } break; case WTOK_SFX: diff --git a/src/kart.cpp b/src/kart.cpp index 53bff5022..6bc2fccec 100644 --- a/src/kart.cpp +++ b/src/kart.cpp @@ -376,12 +376,6 @@ 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==race_manager->getNumLaps()-1 && - race_manager->getRaceMode()!=RaceManager::RM_FOLLOW_LEADER) // 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_information.cpp b/src/music_information.cpp index a29afa98c..a44953f93 100755 --- a/src/music_information.cpp +++ b/src/music_information.cpp @@ -27,6 +27,8 @@ #include "track_manager.hpp" #include "track.hpp" #include "translation.hpp" +#include "user_config.hpp" +#include "music_ogg.hpp" #if defined(WIN32) && !defined(__CYGWIN__) # define snprintf _snprintf @@ -39,6 +41,8 @@ MusicInformation::MusicInformation(const std::string& filename) m_numLoops = LOOP_FOREVER; m_normal_filename = ""; m_fast_filename = ""; + m_normal_music = NULL; + m_fast_music = NULL; m_faster_time = 1.0f; m_max_pitch = 0.1f; @@ -96,7 +100,7 @@ MusicInformation::MusicInformation(const std::string& filename) } // MusicInformation //----------------------------------------------------------------------------- -void MusicInformation::addMusicToTracks() const +void MusicInformation::addMusicToTracks() { for(int i=0; i<(int)m_all_tracks.size(); i++) { @@ -106,3 +110,146 @@ void MusicInformation::addMusicToTracks() const } // addMusicToTracks //----------------------------------------------------------------------------- +void MusicInformation::startMusic() +{ + m_time_since_faster = 0.0f; + m_mode = SOUND_NORMAL; + + if (m_normal_filename== "") return; + + // First load the 'normal' music + // ----------------------------- + if(StringUtils::extension(m_normal_filename)!="ogg") + { + fprintf(stderr, "WARNING: music file %s format not recognized.\n", + m_normal_filename.c_str()); + return; + } + m_normal_music = new MusicOggStream(); + + if((m_normal_music->load(m_normal_filename)) == false) + { + delete m_normal_music; + m_normal_music=0; + fprintf(stderr, "WARNING: Unabled to load music %s, not supported or not found.\n", + m_normal_filename.c_str()); + return; + } + m_normal_music->playMusic(); + + // Then (if available) load the music for the last track + // ----------------------------------------------------- + if(m_fast_filename=="") + { + m_fast_music = NULL; + return; // no fast music + } + + if(StringUtils::extension(m_fast_filename)!="ogg") + { + fprintf(stderr, + "WARNING: music file %s format not recognized, fast music is ignored\n", + m_fast_filename.c_str()); + return; + } + m_fast_music= new MusicOggStream(); + + if((m_fast_music->load(m_fast_filename)) == false) + { + delete m_fast_music; + m_fast_music=0; + fprintf(stderr, "WARNING: Unabled to load fast music %s, not supported or not found.\n", + m_fast_filename.c_str()); + return; + } +} // startMusic + +//----------------------------------------------------------------------------- +void MusicInformation::update(float dt) +{ + switch(m_mode) + { + case SOUND_FADING: { + m_time_since_faster +=dt; + if(m_time_since_faster>=m_faster_time) + { + m_mode=SOUND_FAST; + m_normal_music->stopMusic(); + m_fast_music->update(); + return; + } + float fraction=m_time_since_faster/m_faster_time; + m_normal_music->updateFading(1-fraction); + m_fast_music->updateFading(fraction); + break; + } + case SOUND_FASTER: { + m_time_since_faster +=dt; + if(m_time_since_faster>=m_faster_time) + { + // Once the pitch is adjusted, just switch back to normal + // mode. We can't switch to fast music mode, since this would + // play m_fast_music, which isn't available. + m_mode=SOUND_NORMAL; + return; + } + float fraction=m_time_since_faster/m_faster_time; + m_normal_music->updateFaster(fraction, m_max_pitch); + + break; + } + case SOUND_NORMAL: + m_normal_music->update(); + break; + case SOUND_FAST: + m_fast_music->update(); + break; + } // switch + +} // update + +//----------------------------------------------------------------------------- +void MusicInformation::stopMusic() +{ + if (m_normal_music != NULL) + { + m_normal_music->stopMusic(); + m_normal_music = NULL; + } + if (m_fast_music != NULL) + { + m_fast_music->stopMusic(); + m_fast_music=NULL; + } +} // stopMusic + +//----------------------------------------------------------------------------- +void MusicInformation::pauseMusic() +{ + if (m_normal_music != NULL) m_normal_music->pauseMusic(); + if (m_fast_music != NULL) m_fast_music->pauseMusic(); +} // pauseMusic +//----------------------------------------------------------------------------- +void MusicInformation::resumeMusic() +{ + if (m_normal_music != NULL) m_normal_music->resumeMusic(); + if (m_fast_music != NULL) m_fast_music->resumeMusic(); +} // resumeMusic + +//----------------------------------------------------------------------------- +void MusicInformation::switchToFastMusic() +{ + m_time_since_faster = 0.0f; + if(m_fast_music) + { + m_mode = SOUND_FADING; + m_fast_music->playMusic(); + } + else + { + // FIXME: for now this music is too annoying, + m_mode = SOUND_FASTER; + } +} // switchToFastMusic + +//----------------------------------------------------------------------------- diff --git a/src/music_information.hpp b/src/music_information.hpp index 9752b855f..e8e2b703a 100755 --- a/src/music_information.hpp +++ b/src/music_information.hpp @@ -22,6 +22,7 @@ #include #include +#include "music.hpp" class MusicInformation { @@ -36,6 +37,15 @@ private: // music in, or time to change pitch float m_max_pitch; // maximum pitch for faster music static const int LOOP_FOREVER=-1; + Music *m_normal_music, + *m_fast_music; + enum {SOUND_NORMAL, // normal music is played + SOUND_FADING, // normal music fading out, faster fading in + SOUND_FASTER, // change pitch of normal music + SOUND_FAST} // playing faster music or max pitch reached + m_mode; + float m_time_since_faster; + public: MusicInformation (const std::string& filename); const std::string& getComposer () const {return m_composer; } @@ -45,6 +55,12 @@ public: int getNumLoops () const {return m_numLoops; } float getFasterTime () const {return m_faster_time; } float getMaxPitch () const {return m_max_pitch; } - void addMusicToTracks () const; + void addMusicToTracks (); + void update (float dt); + void startMusic (); + void stopMusic (); + void pauseMusic (); + void resumeMusic (); + void switchToFastMusic(); }; // MusicInformation #endif diff --git a/src/sound_manager.cpp b/src/sound_manager.cpp index 4471da96f..3c7cf5a5c 100644 --- a/src/sound_manager.cpp +++ b/src/sound_manager.cpp @@ -45,9 +45,7 @@ SoundManager* sound_manager= NULL; SoundManager::SoundManager() : m_sfxs(NUM_SOUNDS) { - m_normal_music = NULL; - m_fast_music = NULL; - + m_current_music= NULL; if(alutInit(0, NULL) == AL_TRUE) // init OpenAL sound system m_initialized = true; else @@ -94,17 +92,6 @@ SoundManager::~SoundManager() } m_sfxs.empty(); - if (m_normal_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) { alutExit(); @@ -137,24 +124,24 @@ void SoundManager::loadMusicFromOneDir(const std::string& dir) } // loadMusicFromOneDir //----------------------------------------------------------------------------- -void SoundManager::addMusicToTracks() const +void SoundManager::addMusicToTracks() { - for(std::map::const_iterator i=m_allMusic.begin(); - i!=m_allMusic.end(); i++) + for(std::map::iterator i=m_allMusic.begin(); + i!=m_allMusic.end(); i++) { i->second->addMusicToTracks(); } } // addMusicToTracks //----------------------------------------------------------------------------- -const MusicInformation* SoundManager::getMusicInformation(const std::string& filename) +MusicInformation* SoundManager::getMusicInformation(const std::string& filename) { if(filename=="") { return NULL; } const std::string basename = StringUtils::basename(filename); - const MusicInformation* mi = m_allMusic[basename]; + MusicInformation* mi = m_allMusic[basename]; if(!mi) { mi = new MusicInformation(filename); @@ -173,181 +160,20 @@ void SoundManager::playSfx(unsigned int id) } // playSfx //----------------------------------------------------------------------------- -void SoundManager::playMusic(const MusicInformation* mi) +void SoundManager::startMusic(MusicInformation* mi) { - m_music_information = mi; - m_time_since_faster = 0.0f; - m_mode = SOUND_NORMAL; + m_current_music = mi; + if(!user_config->doMusic() || !m_initialized) return; - if (m_normal_music != NULL) - { - delete m_normal_music; - m_normal_music = NULL; - } - - if (mi->getNormalFilename()== "") // nothing to play - { - return; - } - - // First load the 'normal' music - // ----------------------------- - const std::string& filename_normal=mi->getNormalFilename(); - if(StringUtils::extension(filename_normal)!="ogg") - { - 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_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(filename_fast=="") - { - m_fast_music = NULL; - return; // no fast music - } - - 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; - } - -} // playMusic + mi->startMusic(); +} // startMusic //----------------------------------------------------------------------------- void SoundManager::stopMusic() { - if (m_normal_music != NULL) - { - m_normal_music->stopMusic(); - } - if (m_fast_music != NULL) - { - m_fast_music->stopMusic(); - } - m_music_information = NULL; + if(m_current_music) m_current_music->stopMusic(); + m_current_music=NULL; } // stopMusic //----------------------------------------------------------------------------- -void SoundManager::pauseMusic() -{ - if (m_normal_music != NULL) - { - 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_mode!=SOUND_NORMAL) return; // ignore if already fast - - m_time_since_faster = 0.0f; - if(m_fast_music) - { - m_mode = SOUND_FADING; - m_fast_music->playMusic(); - } - else - { - // FIXME: for now this music is too annoying, - // m_mode = SOUND_FASTER; - } -} // switchToFastMusic -//----------------------------------------------------------------------------- - -void SoundManager::resumeMusic() -{ - if (m_normal_music != NULL) - { - m_normal_music->resumeMusic(); - } - if (m_fast_music != NULL) - { - m_fast_music->resumeMusic(); - } -} // resumeMusic - -//----------------------------------------------------------------------------- -void SoundManager::update(float dt) -{ - if (m_normal_music != NULL) - { - switch(m_mode) - { - case SOUND_FADING: { - if(!m_music_information) return; - m_time_since_faster +=dt; - if(m_time_since_faster>=m_music_information->getFasterTime()) - { - m_mode=SOUND_FAST; - m_normal_music->stopMusic(); - m_fast_music->update(); - return; - } - float fraction=m_time_since_faster/m_music_information->getFasterTime(); - m_normal_music->updateFading(1-fraction); - m_fast_music->updateFading(fraction); - break; - } - case SOUND_FASTER: { - if(!m_music_information) return; - m_time_since_faster +=dt; - if(m_time_since_faster>=m_music_information->getFasterTime()) - { - // Once the pitch is adjusted, just switch back to normal - // mode. We can't switch to fast music mode, since this would - // play m_fast_music, which isn't available. - m_mode=SOUND_NORMAL; - return; - } - float fraction=m_time_since_faster/m_music_information->getFasterTime(); - m_normal_music->updateFaster(fraction, - m_music_information->getMaxPitch()); - - 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 3cb83c59f..e7bf031ec 100644 --- a/src/sound_manager.hpp +++ b/src/sound_manager.hpp @@ -44,38 +44,30 @@ private: typedef std::vector SFXsType; SFXsType m_sfxs; - Music *m_normal_music, - *m_fast_music; - MusicInformation const *m_music_information; + MusicInformation *m_current_music; 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 + std::map m_allMusic; void loadMusicInformation(); - enum {SOUND_NORMAL, // normal music is played - SOUND_FADING, // normal music fading out, faster music fading in - SOUND_FASTER, // change pitch of normal music (i.e. no faster avail) - SOUND_FAST} // playing faster music or max pitch reached - m_mode; - float m_time_since_faster; public: SoundManager(); virtual ~SoundManager(); - void update(float dt); void playSfx(unsigned int id); - void playMusic(const MusicInformation* mi); + void startMusic(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 update(float dt) {m_current_music->update(dt); } + void pauseMusic() {m_current_music->pauseMusic(); } + void resumeMusic() {m_current_music->resumeMusic(); } + void switchToFastMusic() {m_current_music->switchToFastMusic(); } + MusicInformation *getCurrentMusic() {return m_current_music; } + MusicInformation *getMusicInformation(const std::string& filename); void loadMusicFromOneDir(const std::string& dir); - void addMusicToTracks() const; + void addMusicToTracks(); }; diff --git a/src/track.cpp b/src/track.cpp index abb5c4353..d7d10f2f1 100644 --- a/src/track.cpp +++ b/src/track.cpp @@ -848,13 +848,13 @@ void Track::loadTrack(std::string filename_) } // loadTrack //----------------------------------------------------------------------------- -void Track::getMusicInformation(std::vector& filenames, - std::vector& music ) +void Track::getMusicInformation(std::vector& filenames, + std::vector& music ) { for(int i=0; i<(int)filenames.size(); i++) { std::string full_path = file_manager->getTrackFile(filenames[i], getIdent()); - const MusicInformation* mi; + MusicInformation* mi; try { mi = sound_manager->getMusicInformation(full_path); @@ -874,9 +874,9 @@ void Track::getMusicInformation(std::vector& filenames, } // getMusicInformation //----------------------------------------------------------------------------- -void Track::playMusic() const { - sound_manager->playMusic(m_music[rand()% m_music.size()]); -} // getMusic +void Track::startMusic() const { + sound_manager->startMusic(m_music[rand()% m_music.size()]); +} // startMusic //----------------------------------------------------------------------------- void diff --git a/src/track.hpp b/src/track.hpp index 985110449..2a3775e58 100644 --- a/src/track.hpp +++ b/src/track.hpp @@ -45,8 +45,7 @@ private: std::string m_ident; std::string m_screenshot; std::string m_top_view; - std::vector m_music; - std::vector m_music_last_lap; + std::vector m_music; std::vector m_start_x, m_start_y, m_start_z, m_start_heading; std::string m_herring_style; std::string m_description; @@ -165,16 +164,14 @@ public: void trackToSpatial (sgVec3 xyz, const int SECTOR) const; void loadTrackModel (); bool isShortcut (const int OLDSEC, const int NEWSEC) const; - void addMusic (const MusicInformation* mi) + void addMusic (MusicInformation* mi) {m_music.push_back(mi); } - void addMusicLastLap (const MusicInformation* mi) - {m_music_last_lap.push_back(mi);} ssgBranch* getModel () const {return m_model; } float getGravity () const {return m_gravity; } float getTrackLength () const {return m_total_distance; } const std::string& getIdent () const {return m_ident; } const char* getName () const {return m_name.c_str(); } - void playMusic () const; + void startMusic () const; const std::string& getFilename () const {return m_filename; } const sgVec3& getSunPos () const {return m_sun_position; } const sgVec4& getAmbientCol () const {return m_ambient_col; } @@ -217,7 +214,7 @@ private: int pointInQuad(const sgVec2 A, const sgVec2 B, const sgVec2 C, const sgVec2 D, const sgVec2 POINT ) const; void getMusicInformation(std::vector& filenames, - std::vector& m_music ); + std::vector& m_music ); } ; // class Track diff --git a/src/world.cpp b/src/world.cpp index 741494ef2..0753d754c 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -61,15 +61,16 @@ World::World() #endif { delete world; - world = this; - m_phase = SETUP_PHASE; - m_track = NULL; - m_clock = 0.0f; - m_fastest_lap = 9999999.9f; - m_fastest_kart = 0; - m_eliminated_karts = 0; - m_eliminated_players = 0; - m_leader_intervals = stk_config->m_leader_intervals; + world = this; + m_phase = SETUP_PHASE; + m_track = NULL; + m_clock = 0.0f; + m_faster_music_active = false; + m_fastest_lap = 9999999.9f; + m_fastest_kart = 0; + m_eliminated_karts = 0; + m_eliminated_players = 0; + m_leader_intervals = stk_config->m_leader_intervals; // Grab the track file try @@ -153,7 +154,7 @@ World::World() callback_manager->initAll(); menu_manager->switchToRace(); - m_track->playMusic(); + m_track->startMusic(); m_phase = user_config->m_profile ? RACE_PHASE : SETUP_PHASE; @@ -668,6 +669,18 @@ void World::updateRacePosition ( int k ) } m_kart[k]->setPosition(p); + // Switch on faster music (except in follow leader mode) if not already + // done so, and the first kart is doing its last lap, and the estimated + // remaining time is less than 30 seconds. + if(!m_faster_music_active && + m_kart[k]->getLap()==race_manager->getNumLaps()-1 && + p==1 && + race_manager->getRaceMode()!=RaceManager::RM_FOLLOW_LEADER && + m_kart[k]->estimateFinishTime()-getTime()<30.0f ) + { + sound_manager->switchToFastMusic(); + m_faster_music_active=true; + } } // updateRacePosition //----------------------------------------------------------------------------- @@ -712,17 +725,20 @@ void World::loadTrack() //----------------------------------------------------------------------------- void World::restartRace() { - m_clock = 0.0f; - m_phase = SETUP_PHASE; - m_eliminated_karts = 0; - m_eliminated_players = 0; - m_leader_intervals = stk_config->m_leader_intervals; + m_clock = 0.0f; + m_phase = SETUP_PHASE; + m_faster_music_active = false; + m_eliminated_karts = 0; + m_eliminated_players = 0; + m_leader_intervals = stk_config->m_leader_intervals; for ( Karts::iterator i = m_kart.begin(); i != m_kart.end() ; ++i ) { (*i)->reset(); } resetAllKarts(); + sound_manager->stopMusic(); // Start music from beginning + m_track->startMusic(); herring_manager->reset(); projectile_manager->cleanup(); race_manager->reset(); @@ -776,7 +792,6 @@ void World::pause() //----------------------------------------------------------------------------- void World::unpause() { - sound_manager -> resumeMusic() ; m_phase = RACE_PHASE; } diff --git a/src/world.hpp b/src/world.hpp index 7fdbd40ef..6bc5e3199 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -122,6 +122,7 @@ private: int m_eliminated_players; // number of eliminated players std::vector m_leader_intervals; // time till elimination in follow leader + bool m_faster_music_active; // true if faster music was activated void updateRacePosition( int k ); void loadTrack(); void updateRaceStatus(float dt);