Made it possible to loop sounds in sound sources.

Clarified a FIXME comment. Fixed error reporting.
This part of code needs some refactoring soon.
This commit is contained in:
Karol Nowak 2008-03-11 07:45:38 +00:00
parent 12da898f72
commit bbc4c0bfb9
5 changed files with 31 additions and 17 deletions

View file

@ -1428,18 +1428,20 @@ void event_handler::handle_event_command(const queued_event& event_info,
std::string play_fogged = cfg["check_fogged"];
std::string x = cfg["x"];
std::string y = cfg["y"];
std::string loop = cfg["loop"];
assert(state_of_game != NULL);
if(!sounds.empty() && !delay.empty() && !chance.empty()) {
const std::vector<std::string>& vx = utils::split(x);
const std::vector<std::string>& vy = utils::split(y);
const int loops = lexical_cast_default<int>(loop, 0);
if(play_fogged.empty())
soundsources->add(id, sounds, lexical_cast<int>(delay), lexical_cast<int>(chance));
soundsources->add(id, sounds, lexical_cast<int>(delay), lexical_cast<int>(chance), loops);
else
soundsources->add(id, sounds, lexical_cast<int>(delay),
lexical_cast<int>(chance), utils::string_bool(play_fogged));
lexical_cast<int>(chance), loops, utils::string_bool(play_fogged));
for(unsigned int i = 0; i < minimum(vx.size(), vy.size()); ++i) {
gamemap::location loc(lexical_cast<int>(vx[i]), lexical_cast<int>(vy[i]));

View file

@ -691,9 +691,9 @@ void stop_sound(int id)
reposition_sound(id, DISTANCE_SILENT);
}
void play_sound_positioned(const std::string &files, int id, unsigned int distance)
void play_sound_positioned(const std::string &files, int id, int repeats, unsigned int distance)
{
play_sound_internal(files, SOUND_SOURCES, preferences::sound_on(), 0, distance, id);
play_sound_internal(files, SOUND_SOURCES, preferences::sound_on(), repeats, distance, id);
}
bool play_sound_internal(const std::string& files, channel_group group, bool sound_on, unsigned int repeats,
@ -717,8 +717,12 @@ bool play_sound_internal(const std::string& files, channel_group group, bool sou
return false;
}
channel_ids[channel] = id;
/*
* This check prevents SDL_Mixer from blowing up on Windows when UI sound is played
* in response to toggling the checkbox which disables sound.
*/
if(group != SOUND_UI) {
//FIXME: why is this (group != SOUND_UI) check necessary?
Mix_SetDistance(channel, distance);
}
@ -750,14 +754,20 @@ bool play_sound_internal(const std::string& files, channel_group group, bool sou
}
temp_chunk.group = group;
std::string const &filename = get_binary_file_location("sounds", file);
if (!filename.empty()) {
temp_chunk.set_data(Mix_LoadWAV(filename.c_str()));
} else {
ERR_AUDIO << "Could not load sound with empty filename\n";
return false;
}
if (temp_chunk.get_data() == NULL) {
ERR_AUDIO << "Could not load sound file '" << filename << "': "
<< Mix_GetError() << "\n";
return false;
}
sound_cache.push_front(temp_chunk);
it = sound_cache.begin();
}

View file

@ -67,7 +67,7 @@ void play_sound(const std::string& files, channel_group group = SOUND_FX, unsign
// Play sound, or random one of comma-separated sounds. Use specified
// distance and associate it with specified id (of a sound source).
void play_sound_positioned(const std::string &files, int id, unsigned int distance);
void play_sound_positioned(const std::string &files, int id, int repeats, unsigned int distance);
// Play sound, or random one of comma-separated sounds in bell channel
void play_bell(const std::string& files);

View file

@ -37,7 +37,7 @@ namespace soundsource {
unsigned int manager::positional_source::last_id = 0;
manager::manager(const display &disp) : _disp(disp)
manager::manager(const display &disp) : _disp(disp)
{
_disp.scroll_event().attach_handler(this);
update_positions();
@ -58,16 +58,16 @@ void manager::handle_generic_event(const std::string &event_name)
update_positions();
}
void manager::add(const std::string &id, const std::string &files, int min_delay, int chance, bool play_fogged)
void manager::add(const std::string &id, const std::string &files, int min_delay, int chance, int loop, bool play_fogged)
{
positional_source_iterator it;
if((it = _sources.find(id)) == _sources.end()) {
_sources[id] = new positional_source(files, min_delay, chance, play_fogged);
_sources[id] = new positional_source(files, min_delay, chance, loop, play_fogged);
}
else {
delete (*it).second;
(*it).second = new positional_source(files, min_delay, chance, play_fogged);
(*it).second = new positional_source(files, min_delay, chance, loop, play_fogged);
}
}
@ -110,8 +110,8 @@ void manager::add_location(const std::string &id, const gamemap::location &loc)
}
manager::positional_source::positional_source(const std::string &files, int min_delay, int chance, bool play_fogged)
: _last_played(0), _min_delay(min_delay), _chance(chance),
manager::positional_source::positional_source(const std::string &files, int min_delay, int chance, int loop, bool play_fogged)
: _last_played(0), _min_delay(min_delay), _chance(chance), _loop(loop),
_id(last_id++), _play_fogged(play_fogged), _visible(false),
_files(files)
{
@ -130,7 +130,7 @@ void manager::positional_source::update(unsigned int time, const display &disp)
// If no locations have been specified, treat the source as if
// it was present everywhere on the map
if(_locations.size() == 0) {
sound::play_sound_positioned(_files, last_id, 0); // max volume
sound::play_sound_positioned(_files, last_id, _loop, 0); // max volume
return;
}
@ -152,8 +152,9 @@ void manager::positional_source::update(unsigned int time, const display &disp)
/* }*/
}
if(!sound::is_sound_playing(last_id))
sound::play_sound_positioned(_files, last_id, distance_volume);
if(!sound::is_sound_playing(last_id)) {
sound::play_sound_positioned(_files, last_id, _loop, distance_volume);
}
}
}

View file

@ -36,6 +36,7 @@ class manager : public events::observer {
unsigned int _last_played;
unsigned int _min_delay;
unsigned int _chance;
unsigned int _loop;
unsigned int _id;
bool _play_fogged;
bool _visible;
@ -53,7 +54,7 @@ class manager : public events::observer {
// chance is a chance ;-) (in %) that the sound source will emit
// sound every second after the delay has passed or once the source
// becomes visible
positional_source(const std::string &files, int min_delay, int chance, bool play_fogged = false);
positional_source(const std::string &files, int min_delay, int chance, int loop, bool play_fogged = false);
void update(unsigned int time, const display &disp);
void update_positions(unsigned int time, const display &disp);
@ -80,7 +81,7 @@ public:
void handle_generic_event(const std::string &event_name);
// add or replace a soundsource
void add(const std::string &id, const std::string &files, int min_delay, int chance, bool play_fogged = false);
void add(const std::string &id, const std::string &files, int min_delay, int chance, int loop, bool play_fogged = false);
void remove(const std::string &id);
void update();