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
This commit is contained in:
parent
8417315678
commit
4200f316de
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<std::string> 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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
virtual ~MusicOggStream();
|
||||
|
||||
virtual void update();
|
||||
virtual void updateFading(float percent);
|
||||
|
||||
virtual bool load(const std::string& filename);
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -40,33 +40,39 @@ enum enumSFX {SOUND_UGH, SOUND_WINNER, SOUND_CRASH, SOUND_GRAB,
|
||||
class SoundManager
|
||||
{
|
||||
private:
|
||||
|
||||
typedef std::vector<SFX*> 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<std::string, const MusicInformation*>
|
||||
m_allMusic;
|
||||
void loadMusicInformation();
|
||||
std::map<std::string, const MusicInformation*> 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<SFX*> 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.
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user