1) Improved sound_manager to support separate

sound packages, and using "*.music" information
   files for additional information music. 
2) Removed old/unused plib sound support.
3) Moved all .ogg files to either data/music, or
   to the tracks where they belong.
4) Moved fonts to data/fonts; wav to data/sfx,
   po to data/po, herring to data/herrings,
   models to data/models.



git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1652 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2008-03-14 09:49:17 +00:00
parent ed98654aa7
commit 29dfd09f7c
78 changed files with 463 additions and 241 deletions

0
models/herrings/banana.ac → data/herrings/banana.ac Normal file → Executable file
View File

View File

View File

View File

View File

@ -8,7 +8,7 @@
(grid-order 1 ) ;; order for grand prix, 1 is most
;; points 1st, 0 is least points
;; 1st
(title-music "main_theme.ogg")
(title-music "main_theme.music")
;; Attachment related parameters
;; -----------------------------

View File

@ -1,7 +0,0 @@
# models/herrings
pkgdatadir = $(datadir)/games/@PACKAGE@/models/herrings
pkgdata_DATA = $(wildcard *.ac)
EXTRA_DIST = $(pkgdata_DATA)

Binary file not shown.

View File

@ -1,2 +0,0 @@
Boom boom boom
Matt Thomas

Binary file not shown.

View File

@ -1,3 +0,0 @@
Caribbean Music
Dr.Sternhagel

View File

@ -1,2 +0,0 @@
Ethereal Spectrum
Asha B.

Binary file not shown.

View File

@ -1,2 +0,0 @@
King Arthur's Castle
Magne Djupvik

Binary file not shown.

View File

@ -1,2 +0,0 @@
Lava Lagoon 2
Asha B.

View File

@ -1,7 +0,0 @@
# oggs/
pkgdatadir = $(datadir)/games/@PACKAGE@/oggs
pkgdata_DATA = $(wildcard *.ogg) $(wildcard *.readme)
EXTRA_DIST = $(pkgdata_DATA)

Binary file not shown.

View File

@ -1,2 +0,0 @@
Another Caribbean Beat
Dr.Sternhagel

Binary file not shown.

View File

@ -1,3 +0,0 @@
Desert Dunes
Zhetty

Binary file not shown.

View File

@ -1,3 +0,0 @@
G4M fan track
P@ule

Binary file not shown.

View File

@ -1,2 +0,0 @@
Kart Grand Prix
Weirwood

Binary file not shown.

View File

@ -1,2 +0,0 @@
SuperTuxKart Main Theme
Weirwood

Binary file not shown.

View File

@ -1,2 +0,0 @@
Tuxkart 2
Matt Thomas

Binary file not shown.

View File

@ -1,2 +0,0 @@
Tuxkart 5a
Matt Thomas

Binary file not shown.

View File

@ -1,2 +0,0 @@
Tuxkart 7
Matt Thomas

Binary file not shown.

View File

@ -1,2 +0,0 @@
TuxR
Matt Thomas

View File

@ -36,6 +36,7 @@ supertuxkart_SOURCES = main.cpp \
sound_manager.cpp sound_manager.hpp \
sound_plib.cpp sound_plib.hpp \
music_ogg.cpp music_ogg.hpp \
music_information.cpp music_information.hpp \
sfx_openal.cpp sfx_openal.hpp \
input.hpp \
isect.cpp isect.hpp \

View File

@ -105,8 +105,47 @@ FileManager::FileManager()
m_root_dir.c_str() );
pushTextureSearchPath(m_root_dir+"/data/textures");
pushModelSearchPath (m_root_dir+"/models" );
pushMusicSearchPath (m_root_dir+"/ogg" );
pushModelSearchPath (m_root_dir+"/data/models" );
pushMusicSearchPath (m_root_dir+"/data/music" );
// Add more paths from the STK_MUSIC_PATH environment variable
if(getenv("SUPERTUXKART_MUSIC_PATH")!=NULL)
{
std::string path=getenv("SUPERTUXKART_MUSIC_PATH");
std::vector<std::string> dirs=StringUtils::split(path,':');
for(int i=(int)dirs.size()-1; i>=0; i--)
{
// Remove '/' at the end of paths, since this can cause
// problems with windows when using stat()
while(dirs[i].size()>=1 && dirs[i][dirs[i].size()-1]=='/')
{
dirs[i]=dirs[i].substr(0, dirs[i].size()-1);
}
// remove empty entries
if(dirs[i].size()==0)
{
dirs.erase(dirs.begin()+i);
continue;
}
}
#ifdef WIN32
// Handle filenames like d:/dir, which becomes ["d","/dir"]
for(int i=(int)dirs.size()-1; i>=0; i--)
{
if(dirs[i].size()>1) continue;
if(i==dirs.size()-1) // last element
{
dirs[i]+=":"; // turn "c" back into "c:"
}
else
{
dirs[i]+=":"+dirs[i+1]; // restore "d:/dir" back
dirs.erase(dirs.begin()+i+1);
}
}
#endif
for(int i=0;i<(int)dirs.size(); i++)
pushMusicSearchPath(dirs[i]);
}
} // FileManager
//-----------------------------------------------------------------------------
@ -149,7 +188,7 @@ std::string FileManager::getModelFile(const std::string& FNAME) const
std::string path;
findFile(path, FNAME, m_model_search_path);
return path;
} // makeTexturePath
} // getModelFile
//-----------------------------------------------------------------------------
std::string FileManager::getTrackDir() const
@ -163,6 +202,18 @@ std::string FileManager::getKartDir() const
return m_root_dir+"/data/karts";
} // getKartDir
//-----------------------------------------------------------------------------
std::string FileManager::getHerringDir() const
{
return m_root_dir+"/data/herrings";
} // getHerringDir
//-----------------------------------------------------------------------------
std::vector<std::string> FileManager::getMusicDirs() const
{
return m_music_search_path;
} // getMusicDirs
//-----------------------------------------------------------------------------
std::string FileManager::getTrackFile(const std::string& fname,
const std::string& track_name) const
@ -193,6 +244,12 @@ std::string FileManager::getConfigFile(const std::string& fname) const
return m_root_dir+"/data/"+fname;
} // getConfigFile
//-----------------------------------------------------------------------------
std::string FileManager::getHerringFile(const std::string& fname) const
{
return getHerringDir()+"/"+fname;
} // getConfigFile
//-----------------------------------------------------------------------------
std::string FileManager::getHomeDir() const
{
@ -225,17 +282,20 @@ std::string FileManager::getLogFile(const std::string& fname) const
//-----------------------------------------------------------------------------
std::string FileManager::getMusicFile(const std::string& fname) const
{
return m_root_dir+"/oggs/"+fname;
std::string path;
findFile(path, fname, m_music_search_path);
return path;
} // getMusicFile
//-----------------------------------------------------------------------------
std::string FileManager::getSFXFile(const std::string& fname) const
{
return m_root_dir+"/sfx/"+fname;
return m_root_dir+"/data/sfx/"+fname;
} // getSFXFile
//-----------------------------------------------------------------------------
std::string FileManager::getFontFile(const std::string& fname) const
{
return m_root_dir+"/fonts/"+fname;
return m_root_dir+"/data/fonts/"+fname;
} // getFontFile
//-----------------------------------------------------------------------------
std::string FileManager::getHighscoreFile(const std::string& fname) const
@ -270,12 +330,12 @@ void FileManager::initConfigDir()
//-----------------------------------------------------------------------------
void FileManager::listFiles(std::set<std::string>& result, const std::string& dir,
bool is_full_path) const
bool is_full_path, bool make_full_path) const
{
struct stat mystat;
// don't list directories with a slash on the end, it'll fail on win32
assert(dir[dir.size()-1] != '/');
// assert(dir[dir.size()-1] != '/');
result.clear();
@ -290,7 +350,8 @@ void FileManager::listFiles(std::set<std::string>& result, const std::string& di
ulDirEnt* mydirent;
while( (mydirent = ulReadDir(mydir)) != 0)
{
result.insert(mydirent->d_name);
result.insert(make_full_path ? path+"/"+mydirent->d_name
: mydirent->d_name);
}
ulCloseDir(mydir);
} // listFiles

View File

@ -43,6 +43,8 @@ public:
std::string getHomeDir () const;
std::string getTrackDir () const;
std::string getKartDir () const;
std::string getHerringDir () const;
std::vector<std::string>getMusicDirs() const;
std::string getTextureFile (const std::string& fname) const;
std::string getKartFile (const std::string& fname,
const std::string& kart="") const;
@ -51,6 +53,7 @@ public:
std::string getConfigFile (const std::string& fname) const;
std::string getHighscoreFile(const std::string& fname) const;
std::string getLogFile (const std::string& fname) const;
std::string getHerringFile (const std::string& fname) const;
std::string getMusicFile (const std::string& fname) const;
std::string getSFXFile (const std::string& fname) const;
std::string getFontFile (const std::string& fname) const;
@ -60,7 +63,7 @@ public:
#endif
void listFiles(std::set<std::string>& result, const std::string& dir,
bool is_full_path=false)
bool is_full_path=false, bool make_full_path=false)
const;
void pushTextureSearchPath(const std::string& path)

View File

@ -103,7 +103,7 @@ void ConfigSound::select()
{
user_config->setMusic(UserConfig::UC_ENABLE);
widget_manager->setWgtText(WTOK_MUSIC, _("Turn off music"));
sound_manager->playMusic(sound_manager->getCurrentMusicFile());
sound_manager->playMusic(sound_manager->getCurrentMusic());
}
break;
case WTOK_SFX:

View File

@ -838,19 +838,21 @@ void RaceGUI::addMessage(const char *msg, Kart *kart, float time,
// usually the title and composer.
void RaceGUI::drawMusicDescription()
{
const std::vector<std::string>& description = sound_manager->getDescription();
const MusicInformation* mi=sound_manager->getCurrentMusic();
int y=0;
for(int i=(int)description.size()-1; i>=0; i--)
if(mi->getComposer()!="")
{
std::string s=description[i];
if(i==0) s="\""+s+"\"";
if(i==1) s="by "+s;
std::string s="by "+mi->getComposer();
font_race->Print( s.c_str(), 25,
Font::CENTER_OF_SCREEN, y,
255, 255, 255);
y+=20;
} // for i<m_description.size()
}
std::string s="\""+mi->getTitle()+"\"";
font_race->Print( s.c_str(), 25,
Font::CENTER_OF_SCREEN, y,
255, 255, 255);
} // drawMusicDescription
//-----------------------------------------------------------------------------

View File

@ -117,20 +117,21 @@ HerringManager::~HerringManager()
//-----------------------------------------------------------------------------
void HerringManager::loadDefaultHerrings()
{
// Load all models. This can't be done in the constructor, since the file_manager
// isn't ready at that stage.
// Load all models from the models/herrings directory
// --------------------------------------------------
// Load all models. This can't be done in the constructor,
// since the file_manager isn't ready at that stage.
// -------------------------------------------------------
std::set<std::string> files;
file_manager->listFiles(files, "models/herrings");
file_manager->listFiles(files, file_manager->getHerringDir(),
/*is_full_path*/true,
/*make_full_path*/true);
for(std::set<std::string>::iterator i = files.begin();
i != files.end(); ++i)
{
if(!StringUtils::has_suffix(*i, ".ac")) continue;
std::string fullName = "herrings/"+(*i);
ssgEntity* h = loader->load(fullName, CB_HERRING);
std::string shortName = StringUtils::without_extension(*i);
ssgEntity* h = loader->load(*i, CB_HERRING,
/*optimise*/true,
/*full_path*/true);
std::string shortName = StringUtils::basename(StringUtils::without_extension(*i));
h->ref();
h->setName(shortName.c_str());
m_all_models[shortName] = h;

View File

@ -786,6 +786,10 @@
RelativePath="../../../src\moving_texture.cpp"
>
</File>
<File
RelativePath="..\..\music_information.cpp"
>
</File>
<File
RelativePath="../../../src\music_ogg.cpp"
>
@ -1196,6 +1200,10 @@
RelativePath="../../../src\music.hpp"
>
</File>
<File
RelativePath="..\..\music_information.hpp"
>
</File>
<File
RelativePath="../../../src\music_ogg.hpp"
>

View File

@ -67,7 +67,6 @@ void KartPropertiesManager::loadKartData(bool dont_load_models)
i != result.end(); ++i)
{
std::string kart_file;
if(*i=="." || *i=="..") continue;
try
{
kart_file = file_manager->getKartFile((*i)+".kart");

View File

@ -390,8 +390,8 @@ void InitTuxkart()
herring_manager = new HerringManager ();
attachment_manager = new AttachmentManager ();
highscore_manager = new HighscoreManager ();
track_manager ->loadTrackList () ;
track_manager->loadTrackList();
sound_manager->addMusicToTracks();
// default settings for Quickstart
race_manager->setNumPlayers(1);
race_manager->setNumLaps (3);

88
src/music_information.cpp Executable file
View File

@ -0,0 +1,88 @@
// $Id: music_information.cpp 1610 2008-03-01 03:18:53Z hikerstk $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "music_information.hpp"
#include "lisp/lisp.hpp"
#include "lisp/parser.hpp"
#include "string_utils.hpp"
#include "track_manager.hpp"
#include "track.hpp"
#include "translation.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
MusicInformation::MusicInformation(const std::string& filename)
{
m_title = "";
m_composer = "";
m_numLoops = LOOP_FOREVER;
if(StringUtils::extension(filename)!="music")
{
// Create information just from ogg file
// -------------------------------------
m_title = StringUtils::without_extension(StringUtils::basename(filename));
m_ogg_filename = filename;
return;
}
// Otherwise read config file
// --------------------------
lisp::Parser parser;
const lisp::Lisp* const ROOT = parser.parse(filename);
const lisp::Lisp* const LISP = ROOT->getLisp("music-information");
if(!LISP)
{
delete ROOT;
char msg[MAX_ERROR_MESSAGE_LENGTH];
snprintf(msg, sizeof(msg),
"Couldn't load music information '%s': no music-information node.",
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);
// 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;
delete ROOT;
} // MusicInformation
//-----------------------------------------------------------------------------
void MusicInformation::addMusicToTracks() const
{
for(int i=0; i<(int)m_all_tracks.size(); i++)
{
Track* track=track_manager->getTrack(m_all_tracks[i]);
if(track) track->addMusic(this);
}
} // addMusicToTracks
//-----------------------------------------------------------------------------

43
src/music_information.hpp Executable file
View File

@ -0,0 +1,43 @@
// $Id: music_information.hpp 1610 2008-03-01 03:18:53Z hikerstk $
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2008 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_MUSIC_INFORMATION
#define HEADER_MUSIC_INFORMATION
#include <string>
#include <vector>
class MusicInformation
{
private:
std::string m_composer;
std::string m_title;
std::string m_ogg_filename;
std::vector<std::string> m_all_tracks;
int m_numLoops;
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
#endif

View File

@ -52,6 +52,7 @@ MusicOggStream::~MusicOggStream()
//-----------------------------------------------------------------------------
bool MusicOggStream::load(const std::string& filename)
{
m_error = true;
if(!release())
{
user_config->setMusic(UserConfig::UC_TEMPORARY_DISABLE);
@ -59,25 +60,32 @@ bool MusicOggStream::load(const std::string& filename)
return false;
}
m_fileName = file_manager->getMusicFile(filename);
//m_fileName = file_manager->getMusicFile(filename);
m_fileName = filename;
if(m_fileName=="") return false;
oggFile = fopen(m_fileName.c_str(), "rb");
m_oggFile = fopen(m_fileName.c_str(), "rb");
#if defined( WIN32 ) || defined( WIN64 )
if( ov_open_callbacks((void *)oggFile, &m_oggStream, NULL, 0, OV_CALLBACKS_DEFAULT) < 0)
#else
if (ov_open(oggFile, &m_oggStream, NULL, 0) < 0)
#endif
if(!m_oggFile)
{
fclose(oggFile);
printf("Loading Music: %s failed\n", m_fileName.c_str());
return false;
}
vorbisInfo = ov_info(&m_oggStream, -1);
#if defined( WIN32 ) || defined( WIN64 )
if( ov_open_callbacks((void *)m_oggFile, &m_oggStream, NULL, 0, OV_CALLBACKS_DEFAULT) < 0)
#else
if (ov_open(m_oggFile, &m_oggStream, NULL, 0) < 0)
#endif
{
fclose(m_oggFile);
printf("Loading Music: %s failed\n", m_fileName.c_str());
return false;
}
m_vorbisInfo = ov_info(&m_oggStream, -1);
if(vorbisInfo->channels == 1)
if(m_vorbisInfo->channels == 1)
nb_channels = AL_FORMAT_MONO16;
else
nb_channels = AL_FORMAT_STEREO16;
@ -85,7 +93,7 @@ bool MusicOggStream::load(const std::string& filename)
alGenBuffers(2, m_soundBuffers);
if(check() == false)
return false;;
return false;
alGenSources(1, &m_soundSource);
if(check() == false)
@ -97,6 +105,7 @@ bool MusicOggStream::load(const std::string& filename)
alSourcef (m_soundSource, AL_ROLLOFF_FACTOR, 0.0 );
alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_TRUE );
m_error=false;
return true;
}
@ -135,7 +144,9 @@ bool MusicOggStream::release()
check();
alDeleteBuffers(2, m_soundBuffers);
check();
ov_clear(&m_oggStream);
// Handle error correctly
if(!m_error) ov_clear(&m_oggStream);
return true;
}
@ -283,7 +294,7 @@ bool MusicOggStream::streamIntoBuffer(ALuint buffer)
return false;
alBufferData(buffer, nb_channels, pcm, size, vorbisInfo->rate);
alBufferData(buffer, nb_channels, pcm, size, m_vorbisInfo->rate);
check();
return true;

View File

@ -31,10 +31,8 @@ using namespace std;
#else
# include <AL/al.h>
#endif
#include "music.hpp"
class MusicOggStream : public Music
{
public:
@ -62,9 +60,10 @@ private:
bool streamIntoBuffer(ALuint buffer);
string m_fileName;
FILE* oggFile;
FILE* m_oggFile;
OggVorbis_File m_oggStream;
vorbis_info* vorbisInfo;
vorbis_info* m_vorbisInfo;
bool m_error;
ALuint m_soundBuffers[2];
ALuint m_soundSource;

View File

@ -2,6 +2,7 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
// Copyright (C) 2008 Patrick Ammann <pammann@aro.ch>, Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -26,22 +27,15 @@
#include "gui/font.hpp"
#include "file_manager.hpp"
#define USE_PLIB_SOUND !(HAVE_OPENAL && HAVE_OGGVORBIS)
#if USE_PLIB_SOUND
# include "sound_plib.hpp"
#else //We use OpenAL
# ifdef __APPLE__
# include <OpenAL/al.h>
# else
# include <AL/al.h>
# endif
# include <AL/alut.h>
#ifdef __APPLE__
# include <OpenAL/al.h>
#else
# include <AL/al.h>
#endif
#include <AL/alut.h>
# if HAVE_OGGVORBIS
# include "music_ogg.hpp"
# endif
# include "sfx_openal.hpp"
#endif // USE_PLIB_SOUND
#include "music_ogg.hpp"
#include "sfx_openal.hpp"
#include "translation.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
@ -49,24 +43,10 @@
#endif
SoundManager* sound_manager= NULL;
SoundManager::SoundManager()
SoundManager::SoundManager() : m_sfxs(NUM_SOUNDS)
{
m_current_music = NULL;
#if USE_PLIB_SOUND
plib_scheduler = new slScheduler;
if(plib_scheduler->notWorking())
{
fprintf(stderr, _("WARNING: Could not initialize the PLIB based sound.\n"));
plib_scheduler->setSafetyMargin(0.25);
m_initialized = false;
}
else
m_initialized = true;
#else
if(alutInit(0, NULL) == AL_TRUE) // init OpenAL sound system
m_initialized = true;
else
@ -76,32 +56,31 @@ SoundManager::SoundManager()
}
alGetError(); //Called here to clear any non-important errors found
#endif
if (m_initialized)
{
// must be in sync with enumSoundSFX
SFX* sfx= NULL;
sfx = new SFXImpl("ugh.wav"); m_sfxs[SOUND_UGH]= sfx;
sfx = new SFXImpl("radio/grandprix_winner.wav"); m_sfxs[SOUND_WINNER] = sfx;
sfx = new SFXImpl("tintagel/grab_collectable.wav"); m_sfxs[SOUND_GRAB] = sfx;
sfx = new SFXImpl("tintagel/crash.wav"); m_sfxs[SOUND_CRASH] = sfx;
sfx = new SFXImpl("radio/shot.wav"); m_sfxs[SOUND_SHOT] = sfx;
sfx = new SFXImpl("explosion.wav"); m_sfxs[SOUND_EXPLOSION] = sfx;
sfx = new SFXImpl("bzzt.wav"); m_sfxs[SOUND_BZZT] = sfx;
sfx = new SFXImpl("radio/horn.wav"); m_sfxs[SOUND_BEEP] = sfx;
sfx = new SFXImpl("radio/slap.wav"); m_sfxs[SOUND_USE_ANVIL] = sfx;
sfx = new SFXImpl("radio/squeaky.wav"); m_sfxs[SOUND_USE_PARACHUTE] = sfx;
sfx = new SFXImpl("wee.wav"); m_sfxs[SOUND_WEE] = sfx;
sfx = new SFXImpl("tintagel/deselect_option.wav"); m_sfxs[SOUND_BACK_MENU] = sfx;
sfx = new SFXImpl("tintagel/select_option.wav"); m_sfxs[SOUND_SELECT_MENU] = sfx;
sfx = new SFXImpl("tintagel/move_option.wav"); m_sfxs[SOUND_MOVE_MENU] = sfx;
sfx = new SFXImpl("tintagel/energy_bar_full.wav"); m_sfxs[SOUND_FULL] = sfx;
sfx = new SFXImpl("tintagel/pre_start_race.wav"); m_sfxs[SOUND_PRESTART] = sfx;
sfx = new SFXImpl("tintagel/start_race.wav"); m_sfxs[SOUND_START] = sfx;
sfx = new SFXImpl("radio/radarping.wav"); m_sfxs[SOUND_MISSILE_LOCK] = sfx;
m_sfxs[SOUND_UGH ] = new SFXImpl("ugh.wav");
m_sfxs[SOUND_WINNER ] = new SFXImpl("radio/grandprix_winner.wav");
m_sfxs[SOUND_GRAB ] = new SFXImpl("tintagel/grab_collectable.wav");
m_sfxs[SOUND_CRASH ] = new SFXImpl("tintagel/crash.wav");
m_sfxs[SOUND_SHOT ] = new SFXImpl("radio/shot.wav");
m_sfxs[SOUND_EXPLOSION ] = new SFXImpl("explosion.wav");
m_sfxs[SOUND_BZZT ] = new SFXImpl("bzzt.wav");
m_sfxs[SOUND_BEEP ] = new SFXImpl("radio/horn.wav");
m_sfxs[SOUND_USE_ANVIL ] = new SFXImpl("radio/slap.wav");
m_sfxs[SOUND_USE_PARACHUTE] = new SFXImpl("radio/squeaky.wav");
m_sfxs[SOUND_WEE ] = new SFXImpl("wee.wav");
m_sfxs[SOUND_BACK_MENU ] = new SFXImpl("tintagel/deselect_option.wav");
m_sfxs[SOUND_SELECT_MENU ] = new SFXImpl("tintagel/select_option.wav");
m_sfxs[SOUND_MOVE_MENU ] = new SFXImpl("tintagel/move_option.wav");
m_sfxs[SOUND_FULL ] = new SFXImpl("tintagel/energy_bar_full.wav");
m_sfxs[SOUND_PRESTART ] = new SFXImpl("tintagel/pre_start_race.wav");
m_sfxs[SOUND_START ] = new SFXImpl("tintagel/start_race.wav");
m_sfxs[SOUND_MISSILE_LOCK ] = new SFXImpl("radio/radarping.wav");
}
loadMusicInformation();
} // SoundManager
//-----------------------------------------------------------------------------
@ -110,8 +89,7 @@ SoundManager::~SoundManager()
// SFX cleanup
for(SFXsType::iterator it= m_sfxs.begin(); it != m_sfxs.end(); it++)
{
SFX* sfx= it->second;
delete sfx;
delete *it;
}
m_sfxs.empty();
@ -123,36 +101,78 @@ SoundManager::~SoundManager()
if(m_initialized)
{
#if USE_PLIB_SOUND
delete plib_scheduler;
#else
alutExit();
#endif
}
} // ~SoundManager
//-----------------------------------------------------------------------------
void SoundManager::loadMusicInformation()
{
// Load music files from data/music, and dirs defined in SUPERTUXKART_MUSIC_PATH
std::vector<std::string> allMusicDirs=file_manager->getMusicDirs();
for(std::vector<std::string>::iterator dir=allMusicDirs.begin();
dir!=allMusicDirs.end(); dir++)
{
loadMusicFromOneDir(*dir);
} // for dir
} // loadMusicInformation
//-----------------------------------------------------------------------------
void SoundManager::loadMusicFromOneDir(const std::string& dir)
{
std::set<std::string> files;
file_manager->listFiles(files, dir, /*is_full_path*/ true,
/*make_full_path*/ true);
for(std::set<std::string>::iterator i = files.begin(); i != files.end(); ++i)
{
if(StringUtils::extension(*i)!="music") continue;
m_allMusic[StringUtils::basename(*i)] = new MusicInformation(*i);
} // for i
} // loadMusicFromOneDir
//-----------------------------------------------------------------------------
void SoundManager::addMusicToTracks() const
{
for(std::map<std::string,const MusicInformation*>::const_iterator i=m_allMusic.begin();
i!=m_allMusic.end(); i++)
{
i->second->addMusicToTracks();
}
} // addMusicToTracks
//-----------------------------------------------------------------------------
const MusicInformation* SoundManager::getMusicInformation(const std::string& filename)
{
if(filename=="")
{
return NULL;
}
const std::string basename=StringUtils::basename(filename);
const MusicInformation* mi=m_allMusic[basename];
if(!mi)
{
mi = new MusicInformation(filename);
m_allMusic[basename] = mi;
}
return mi;
} // SoundManager
//-----------------------------------------------------------------------------
void SoundManager::playSfx(unsigned int id)
{
if(user_config->doSFX() && m_initialized)
if(!user_config->doSFX() || !m_initialized) return;
if (id<0 || id>=m_sfxs.size() || !m_sfxs[id])
{
SFXsType::iterator it= m_sfxs.find(id);
if (it == m_sfxs.end())
{
assert(false);
return;
}
SFX* sfx= it->second;
sfx->play();
assert(false);
}
m_sfxs[id]->play();
} // playSfx
//-----------------------------------------------------------------------------
void SoundManager::playMusic(const std::string& filename)
void SoundManager::playMusic(const MusicInformation* mi)
{
m_description.clear();
m_current_music_file = filename;
m_music_information = mi;
if(!user_config->doMusic() || !m_initialized) return;
if (m_current_music != NULL)
@ -161,20 +181,15 @@ void SoundManager::playMusic(const std::string& filename)
m_current_music = NULL;
}
if (filename == "" || strlen(filename.c_str()) == 0)
if (mi->getFilename()== "")
{
// nothing to play
return;
}
#if USE_PLIB_SOUND
if (!strcasecmp(".mod", filename.c_str()+filename.size()-4))
m_current_music= new MusicPlib();
#endif
#if HAVE_OGGVORBIS
const std::string& filename=mi->getFilename();
if (!strcasecmp(".ogg", filename.c_str()+filename.size()-4))
m_current_music= new MusicOggStream();
#endif
if(m_current_music == NULL) // no support for file
{
fprintf(stderr, "WARNING: music file %s format not recognized.\n", filename.c_str());
@ -185,34 +200,12 @@ void SoundManager::playMusic(const std::string& filename)
{
delete m_current_music;
m_current_music=0;
fprintf(stderr, "WARNING: Unabled to load music %s, not supported or not found.\n",
fprintf(stderr, "WARNING: Unabled to load music %s, not supported or not found.\n",
filename.c_str());
return;
}
m_current_music->playMusic();
// Read up to two lines from the corresponding .readme file: first one
// the title, second the composer. This is then displayed by the race gui
std::string name_readme;
try
{
name_readme = file_manager->getMusicFile(
StringUtils::without_extension(filename)+".readme");
}
catch(std::exception)
{
// Silently ignore any missing .readme files, m_description was cleared above
return;
}
std::ifstream f(name_readme.c_str());
if(f)
{
std::string s;
std::getline(f,s); if(!f.eof()) m_description.push_back(s);
std::getline(f,s); if(!f.eof()) m_description.push_back(s);
f.close();
}
} // playMusic
//-----------------------------------------------------------------------------
@ -222,7 +215,7 @@ void SoundManager::stopMusic()
{
m_current_music->stopMusic();
}
m_description.clear();
m_music_information = NULL;
} // stopMusic
//-----------------------------------------------------------------------------

View File

@ -2,6 +2,7 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006 Patrick Ammann <pammann@aro.ch>
// Copyright (C) 2008 Patrick Ammann <pammann@aro.ch>, Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -25,6 +26,7 @@
#include <string>
#include "music.hpp"
#include "music_information.hpp"
#include "sfx.hpp"
enum enumSFX {SOUND_UGH, SOUND_WINNER, SOUND_CRASH, SOUND_GRAB,
@ -37,29 +39,30 @@ enum enumSFX {SOUND_UGH, SOUND_WINNER, SOUND_CRASH, SOUND_GRAB,
class SoundManager
{
private:
void loadMusicInformation();
std::map<std::string, const MusicInformation*> m_allMusic;
public:
SoundManager();
virtual ~SoundManager();
void update();
void playSfx(unsigned int id);
void playMusic(const std::string& filename);
void stopMusic();
void pauseMusic();
void resumeMusic();
const std::vector<std::string>& getDescription() {return m_description;}
std::string getCurrentMusicFile() {return m_current_music_file;}
void update();
void playSfx(unsigned int id);
void playMusic(const MusicInformation* mi);
void stopMusic();
void pauseMusic();
void resumeMusic();
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::map<int, SFX*> SFXsType;
typedef std::vector<SFX*> SFXsType;
SFXsType m_sfxs;
Music* m_current_music;
std::vector<std::string> m_description;
std::string m_current_music_file;
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

View File

@ -18,6 +18,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stk_config.hpp"
#include "file_manager.hpp"
STKConfig* stk_config=0;
@ -139,7 +140,7 @@ void STKConfig::init_defaults()
m_max_karts = -100;
m_grid_order = -100;
m_title_music = "";
m_title_music = NULL;
} // init_defaults
//-----------------------------------------------------------------------------
@ -166,7 +167,9 @@ void STKConfig::getAllData(const lisp::Lisp* lisp)
lisp->get("explosion-impulse-objects", m_explosion_impulse_objects);
lisp->get("max-karts", m_max_karts );
lisp->get("grid-order", m_grid_order );
lisp->get("title-music", m_title_music );
std::string title_music;
lisp->get("title-music", title_music );
m_title_music = new MusicInformation(file_manager->getMusicFile(title_music));
// Get the default KartProperties
// ------------------------------

View File

@ -21,6 +21,7 @@
#define HEADER_STKCONFIG_H
#include "kart_properties.hpp"
#include "music_information.hpp"
#include "lisp/lisp.hpp"
class STKConfig : public KartProperties
@ -45,7 +46,7 @@ public:
float m_explosion_impulse_objects;// impulse of explosion on moving objects, e.g. road cones, ...
int m_max_karts; // maximum number of karts
int m_grid_order; // whether grand prix grid is in point order or reverse point order
std::string m_title_music; // filename of the title music to play
MusicInformation* m_title_music; // filename of the title music to play
STKConfig() : KartProperties() {};
void init_defaults ();

View File

@ -34,6 +34,19 @@ namespace StringUtils
return strcmp(lhs.c_str()+(lhs.length()-rhs.length()), rhs.c_str())==0;
}
//--------------------------i---------------------------------------------------
std::string path(const std::string& filename)
{
for(int i = int(filename.size()) - 1; i >= 0; --i)
{
if (filename[i]=='/' || filename[i]=='\\')
{
return filename.substr(0,i);
}
}
return "";
}
//-----------------------------------------------------------------------------
std::string basename(const std::string& filename)
{

View File

@ -33,6 +33,9 @@ namespace StringUtils
/** Return the filename part of a path */
std::string basename(const std::string& filename);
/** Return the path (i.e. up to the last / */
std::string path(const std::string& filename);
std::string without_extension(const std::string& filename);
std::string extension(const std::string& filename);

View File

@ -38,6 +38,7 @@
#include "user_config.hpp"
#include "herring.hpp"
#include "herring_manager.hpp"
#include "sound_manager.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
@ -811,7 +812,9 @@ void Track::loadTrack(std::string filename_)
LISP->get ("name", m_name);
LISP->get ("description", m_description);
LISP->getVector("music", m_music_filenames);
std::vector<std::string> filenames;
LISP->getVector("music", filenames);
getMusicInformation(filenames, m_music);
LISP->get ("herring", m_herring_style);
LISP->get ("screenshot", m_screenshot);
LISP->get ("topview", m_top_view);
@ -841,8 +844,33 @@ void Track::loadTrack(std::string filename_)
} // loadTrack
//-----------------------------------------------------------------------------
const std::string& Track::getMusic() const {
return m_music_filenames[rand()% m_music_filenames.size()];
void Track::getMusicInformation(std::vector<std::string>& filenames,
std::vector<MusicInformation const *>& music )
{
for(int i=0; i<(int)filenames.size(); i++)
{
std::string full_path = file_manager->getTrackFile(filenames[i], getIdent());
const MusicInformation* mi;
try
{
mi = sound_manager->getMusicInformation(full_path);
}
catch(std::runtime_error)
{
mi = sound_manager->getMusicInformation(file_manager->getMusicFile(filenames[i]));
}
if(!mi)
{
fprintf(stderr, "Music information file '%s' not found - ignored.\n",filenames[i]);
continue;
}
m_music.push_back(mi);
} // for i in filenames
} // getMusicInformation
//-----------------------------------------------------------------------------
void Track::playMusic() const {
sound_manager->playMusic(m_music[rand()% m_music.size()]);
} // getMusic
//-----------------------------------------------------------------------------

View File

@ -36,6 +36,7 @@
#include "btBulletDynamicsCommon.h"
#include "material.hpp"
#include "triangle_mesh.hpp"
#include "music_information.hpp"
class Track
{
@ -44,7 +45,8 @@ private:
std::string m_ident;
std::string m_screenshot;
std::string m_top_view;
std::vector<std::string> m_music_filenames;
std::vector<MusicInformation const *> m_music;
std::vector<MusicInformation const *> m_music_last_lap;
std::vector<float> m_start_x, m_start_y, m_start_z, m_start_heading;
std::string m_herring_style;
std::string m_description;
@ -163,12 +165,16 @@ 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)
{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(); }
const std::string& getMusic () const;
void playMusic () 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; }
@ -210,6 +216,8 @@ private:
const sgVec2 P ) const;
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 );
}
; // class Track

View File

@ -23,23 +23,23 @@
#include "string_utils.hpp"
#include "track_manager.hpp"
#include "track.hpp"
#include "sound_manager.hpp"
#include "translation.hpp"
TrackManager* track_manager = 0;
TrackManager::TrackManager()
{}
{} // TrackManager
//-----------------------------------------------------------------------------
TrackManager::~TrackManager()
{
for(Tracks::iterator i = m_tracks.begin(); i != m_tracks.end(); ++i)
delete *i;
}
} // ~TrackManager
//-----------------------------------------------------------------------------
Track*
TrackManager::getTrack(const std::string& ident) const
Track* TrackManager::getTrack(const std::string& ident) const
{
for(Tracks::const_iterator i = m_tracks.begin(); i != m_tracks.end(); ++i)
{
@ -50,36 +50,34 @@ TrackManager::getTrack(const std::string& ident) const
char msg[MAX_ERROR_MESSAGE_LENGTH];
fprintf(stderr, "TrackManager: Couldn't find track: '%s'", ident.c_str() );
throw std::runtime_error(msg);
}
} // getTrack
//-----------------------------------------------------------------------------
Track*
TrackManager::getTrack(size_t id) const
Track* TrackManager::getTrack(size_t id) const
{
return m_tracks[id];
}
} // getTrack
//-----------------------------------------------------------------------------
size_t
TrackManager::getTrackCount() const
size_t TrackManager::getTrackCount() const
{
return m_tracks.size();
}
} // getTrackCount
//-----------------------------------------------------------------------------
void
TrackManager::loadTrackList ()
void TrackManager::loadTrackList ()
{
// Load up a list of tracks - and their names
std::set<std::string> files;
file_manager->listFiles(files, file_manager->getTrackDir(), /*is_full_path*/ true);
for(std::set<std::string>::iterator i = files.begin(); i != files.end(); ++i)
std::set<std::string> dirs;
file_manager->listFiles(dirs, file_manager->getTrackDir(), /*is_full_path*/ true);
for(std::set<std::string>::iterator dir = dirs.begin(); dir != dirs.end(); dir++)
{
if(*i=="." || *i=="..") continue;
if(*dir=="." || *dir=="..") continue;
std::string config_file;
try
{
config_file = file_manager->getTrackFile((*i)+".track");
// getTrackFile appends dir, so it's opening: *dir/*dir.track
config_file = file_manager->getTrackFile((*dir)+".track");
}
catch (std::exception& e)
{
@ -90,6 +88,8 @@ TrackManager::loadTrackList ()
if(!f) continue;
m_tracks.push_back(new Track(config_file));
}
}
// Read music files in that dir as well
sound_manager->loadMusicFromOneDir(*dir);
}
} // loadTrackList

View File

@ -161,8 +161,7 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
callback_manager->initAll();
menu_manager->switchToRace();
const std::string& MUSIC_NAME= track_manager->getTrack(m_race_setup.m_track)->getMusic();
if (MUSIC_NAME.size()>0) sound_manager->playMusic(MUSIC_NAME);
m_track->playMusic();
m_phase = user_config->m_profile ? RACE_PHASE : SETUP_PHASE;