2007-05-27 12:01:53 -04:00
|
|
|
// $Id$
|
|
|
|
//
|
|
|
|
// SuperTuxKart - a fun racing game with go-kart
|
|
|
|
// Copyright (C) 2006 SuperTuxKart-Team
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License
|
2008-06-12 20:53:52 -04:00
|
|
|
// as published by the Free Software Foundation; either version 3
|
2007-05-27 12:01:53 -04:00
|
|
|
// 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.
|
|
|
|
|
2009-03-11 23:49:31 -04:00
|
|
|
#include "tracks/track_manager.hpp"
|
2009-01-23 00:23:22 -05:00
|
|
|
|
2008-02-26 20:11:02 -05:00
|
|
|
#include <stdio.h>
|
2007-05-27 12:01:53 -04:00
|
|
|
#include <stdexcept>
|
2008-07-02 23:14:27 -04:00
|
|
|
#include <algorithm>
|
2009-01-23 00:23:22 -05:00
|
|
|
#include <sstream>
|
|
|
|
|
2009-01-22 07:02:40 -05:00
|
|
|
#include "audio/sound_manager.hpp"
|
2009-06-11 06:00:43 -04:00
|
|
|
#include "config/stk_config.hpp"
|
2009-03-11 23:49:31 -04:00
|
|
|
#include "io/file_manager.hpp"
|
|
|
|
#include "tracks/track.hpp"
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
TrackManager* track_manager = 0;
|
|
|
|
|
2009-08-24 01:56:53 -04:00
|
|
|
/** Constructor (currently empty). The real work happens in loadTrackList.
|
2008-09-07 11:31:28 -04:00
|
|
|
*/
|
2007-05-27 12:01:53 -04:00
|
|
|
TrackManager::TrackManager()
|
2008-03-14 05:49:17 -04:00
|
|
|
{} // TrackManager
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-09-07 11:31:28 -04:00
|
|
|
/** Delete all tracks.
|
|
|
|
*/
|
2007-05-27 12:01:53 -04:00
|
|
|
TrackManager::~TrackManager()
|
|
|
|
{
|
|
|
|
for(Tracks::iterator i = m_tracks.begin(); i != m_tracks.end(); ++i)
|
|
|
|
delete *i;
|
2008-03-14 05:49:17 -04:00
|
|
|
} // ~TrackManager
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2009-08-24 01:56:53 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Adds a directory from which tracks are loaded. The track manager checks if
|
|
|
|
* either this directory itself contains a track, and if any subdirectory
|
|
|
|
* contains a track.
|
|
|
|
* \param dir The directory to add.
|
|
|
|
*/
|
|
|
|
void TrackManager::addTrackDir(const std::string &dir)
|
|
|
|
{
|
|
|
|
m_track_dirs.push_back(dir);
|
|
|
|
} // addTrackDir
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2008-09-07 11:31:28 -04:00
|
|
|
/** Get TrackData by the track identifier.
|
|
|
|
* \param ident Identifier = filename without .track
|
|
|
|
*/
|
2008-03-14 05:49:17 -04:00
|
|
|
Track* TrackManager::getTrack(const std::string& ident) const
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
|
|
|
for(Tracks::const_iterator i = m_tracks.begin(); i != m_tracks.end(); ++i)
|
|
|
|
{
|
|
|
|
if ((*i)->getIdent() == ident)
|
|
|
|
return *i;
|
|
|
|
}
|
|
|
|
|
2009-01-23 00:23:22 -05:00
|
|
|
std::ostringstream msg;
|
|
|
|
msg<<"TrackManager: Couldn't find track: '"<<ident<<"'";
|
|
|
|
throw std::runtime_error(msg.str());
|
2008-03-14 05:49:17 -04:00
|
|
|
} // getTrack
|
2007-05-27 12:01:53 -04:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-09-07 11:31:28 -04:00
|
|
|
/** Marks the specified track as unavailable (i.e. not available on all
|
|
|
|
* clients and server.
|
|
|
|
* \param ident Track identifier (i.e. track name without .track)
|
|
|
|
*/
|
|
|
|
void TrackManager::unavailable(const std::string& ident)
|
|
|
|
{
|
|
|
|
for(Tracks::const_iterator i = m_tracks.begin(); i != m_tracks.end(); ++i)
|
|
|
|
{
|
|
|
|
if ((*i)->getIdent() == ident)
|
|
|
|
{
|
|
|
|
m_track_avail[i-m_tracks.begin()] = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Do nothing if the track does not exist here ... it's not available.
|
|
|
|
return;
|
|
|
|
} // unavailable
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Sets all tracks that are not in the list a to be unavailable. This is used
|
|
|
|
* by the network manager upon receiving the list of available tracks from
|
|
|
|
* a client.
|
|
|
|
* \param tracks List of all track identifiere (available on a client).
|
|
|
|
*/
|
|
|
|
void TrackManager::setUnavailableTracks(const std::vector<std::string> &tracks)
|
|
|
|
{
|
|
|
|
for(Tracks::const_iterator i = m_tracks.begin(); i != m_tracks.end(); ++i)
|
|
|
|
{
|
|
|
|
if(!m_track_avail[i-m_tracks.begin()]) continue;
|
|
|
|
const std::string id=(*i)->getIdent();
|
|
|
|
if (std::find(tracks.begin(), tracks.end(), id)==tracks.end())
|
|
|
|
{
|
|
|
|
m_track_avail[i-m_tracks.begin()] = false;
|
|
|
|
fprintf(stderr, "Track '%s' not available on all clients, disabled.\n",
|
|
|
|
id.c_str());
|
|
|
|
} // if id not in tracks
|
|
|
|
} // for all available tracks in track manager
|
|
|
|
|
|
|
|
} // setUnavailableTracks
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/** Returns a list with all track identifiert.
|
|
|
|
*/
|
|
|
|
std::vector<std::string> TrackManager::getAllTrackIdentifiers()
|
|
|
|
{
|
|
|
|
std::vector<std::string> all;
|
|
|
|
for(Tracks::const_iterator i = m_tracks.begin(); i != m_tracks.end(); ++i)
|
|
|
|
{
|
|
|
|
all.push_back((*i)->getIdent());
|
|
|
|
}
|
|
|
|
return all;
|
|
|
|
} // getAllTrackNames
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-10-14 16:20:54 -04:00
|
|
|
/** Loads all tracks from the track directory (data/track).
|
2008-09-07 11:31:28 -04:00
|
|
|
*/
|
2008-03-14 05:49:17 -04:00
|
|
|
void TrackManager::loadTrackList ()
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
|
|
|
// Load up a list of tracks - and their names
|
2008-03-14 05:49:17 -04:00
|
|
|
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++)
|
2008-02-26 20:11:02 -05:00
|
|
|
{
|
2008-03-14 05:49:17 -04:00
|
|
|
if(*dir=="." || *dir=="..") continue;
|
2008-02-26 20:11:02 -05:00
|
|
|
std::string config_file;
|
|
|
|
try
|
|
|
|
{
|
2008-03-14 05:49:17 -04:00
|
|
|
// getTrackFile appends dir, so it's opening: *dir/*dir.track
|
2009-03-12 01:21:13 -04:00
|
|
|
// FIXME: rename from .irrtrack to .track
|
2009-02-19 20:42:34 -05:00
|
|
|
config_file = file_manager->getTrackFile((*dir)+".irrtrack");
|
2008-02-26 20:11:02 -05:00
|
|
|
}
|
|
|
|
catch (std::exception& e)
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2008-02-26 20:11:02 -05:00
|
|
|
(void)e; // remove warning about unused variable
|
|
|
|
continue;
|
2007-05-27 12:01:53 -04:00
|
|
|
}
|
2008-02-26 20:11:02 -05:00
|
|
|
FILE *f=fopen(config_file.c_str(),"r");
|
|
|
|
if(!f) continue;
|
2008-07-29 00:30:44 -04:00
|
|
|
fclose(f);
|
2008-02-26 20:11:02 -05:00
|
|
|
|
2008-07-02 23:14:27 -04:00
|
|
|
Track *track = new Track(config_file);
|
2009-01-16 06:13:55 -05:00
|
|
|
if(track->getVersion()<stk_config->m_min_track_version ||
|
|
|
|
track->getVersion()>stk_config->m_max_track_version)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Warning: track '%s' is not supported by this binary, ignored.\n",
|
|
|
|
track->getIdent().c_str());
|
|
|
|
delete track;
|
|
|
|
continue;
|
|
|
|
}
|
2008-07-02 23:14:27 -04:00
|
|
|
m_tracks.push_back(track);
|
2008-09-07 11:31:28 -04:00
|
|
|
m_track_avail.push_back(true);
|
2008-07-02 23:14:27 -04:00
|
|
|
updateGroups(track);
|
2008-03-14 05:49:17 -04:00
|
|
|
// Read music files in that dir as well
|
|
|
|
sound_manager->loadMusicFromOneDir(*dir);
|
|
|
|
}
|
|
|
|
} // loadTrackList
|
2008-07-02 23:14:27 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-09-07 11:31:28 -04:00
|
|
|
/** Updates the groups after a track was read in.
|
|
|
|
* \param track Pointer to the new track, whose groups are now analysed.
|
|
|
|
*/
|
2008-07-02 23:14:27 -04:00
|
|
|
void TrackManager::updateGroups(const Track* track)
|
|
|
|
{
|
|
|
|
const std::vector<std::string>& new_groups = track->getGroups();
|
2008-10-14 16:20:54 -04:00
|
|
|
const bool isArena = track->isArena();
|
|
|
|
|
|
|
|
const unsigned int groups_amount = new_groups.size();
|
|
|
|
for(unsigned int i=0; i<groups_amount; i++)
|
2008-07-02 23:14:27 -04:00
|
|
|
{
|
2008-10-14 16:20:54 -04:00
|
|
|
// if we didn't yet have this group in memory, add it to the global list
|
|
|
|
if(m_groups.find(new_groups[i])==m_groups.end() &&
|
|
|
|
m_arena_groups.find(new_groups[i])==m_arena_groups.end())
|
2008-07-21 02:28:33 -04:00
|
|
|
m_all_groups.push_back(new_groups[i]);
|
2008-10-14 16:20:54 -04:00
|
|
|
|
|
|
|
// add this track to its group
|
|
|
|
if(isArena) m_arena_groups[new_groups[i]].push_back(m_tracks.size()-1);
|
|
|
|
else m_groups[new_groups[i]].push_back(m_tracks.size()-1);
|
2008-07-02 23:14:27 -04:00
|
|
|
}
|
|
|
|
} // updateGroups
|
|
|
|
|
2008-09-07 10:12:14 -04:00
|
|
|
// ----------------------------------------------------------------------------
|