1) Redesigned music_information and sound_manager interaction.

2) The faster music is now only triggered for the last 30 seconds
   of a race.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1825 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2008-05-08 01:28:07 +00:00
parent 89b26ff5a5
commit 76429aa5ab
11 changed files with 236 additions and 247 deletions

View File

@ -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())
{

View File

@ -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:

View File

@ -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)

View File

@ -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
//-----------------------------------------------------------------------------

View File

@ -22,6 +22,7 @@
#include <string>
#include <vector>
#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

View File

@ -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<std::string,const MusicInformation*>::const_iterator i=m_allMusic.begin();
i!=m_allMusic.end(); i++)
for(std::map<std::string,MusicInformation*>::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

View File

@ -44,38 +44,30 @@ private:
typedef std::vector<SFX*> 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::string, const MusicInformation*>
std::map<std::string, MusicInformation*>
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();
};

View File

@ -848,13 +848,13 @@ void Track::loadTrack(std::string filename_)
} // loadTrack
//-----------------------------------------------------------------------------
void Track::getMusicInformation(std::vector<std::string>& filenames,
std::vector<MusicInformation const *>& music )
void Track::getMusicInformation(std::vector<std::string>& filenames,
std::vector<MusicInformation*>& 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<std::string>& 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

View File

@ -45,8 +45,7 @@ private:
std::string m_ident;
std::string m_screenshot;
std::string m_top_view;
std::vector<MusicInformation const *> m_music;
std::vector<MusicInformation const *> m_music_last_lap;
std::vector<MusicInformation*> m_music;
std::vector<float> 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<std::string>& filenames,
std::vector<MusicInformation const*>& m_music );
std::vector<MusicInformation*>& m_music );
}
; // class Track

View File

@ -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;
}

View File

@ -122,6 +122,7 @@ private:
int m_eliminated_players; // number of eliminated players
std::vector<float>
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);