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 play_fogged = cfg["check_fogged"];
std::string x = cfg["x"]; std::string x = cfg["x"];
std::string y = cfg["y"]; std::string y = cfg["y"];
std::string loop = cfg["loop"];
assert(state_of_game != NULL); assert(state_of_game != NULL);
if(!sounds.empty() && !delay.empty() && !chance.empty()) { if(!sounds.empty() && !delay.empty() && !chance.empty()) {
const std::vector<std::string>& vx = utils::split(x); const std::vector<std::string>& vx = utils::split(x);
const std::vector<std::string>& vy = utils::split(y); const std::vector<std::string>& vy = utils::split(y);
const int loops = lexical_cast_default<int>(loop, 0);
if(play_fogged.empty()) 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 else
soundsources->add(id, sounds, lexical_cast<int>(delay), 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) { 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])); 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); 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, 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; return false;
} }
channel_ids[channel] = id; 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) { if(group != SOUND_UI) {
//FIXME: why is this (group != SOUND_UI) check necessary?
Mix_SetDistance(channel, distance); 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; temp_chunk.group = group;
std::string const &filename = get_binary_file_location("sounds", file); std::string const &filename = get_binary_file_location("sounds", file);
if (!filename.empty()) { if (!filename.empty()) {
temp_chunk.set_data(Mix_LoadWAV(filename.c_str())); 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) { if (temp_chunk.get_data() == NULL) {
ERR_AUDIO << "Could not load sound file '" << filename << "': " ERR_AUDIO << "Could not load sound file '" << filename << "': "
<< Mix_GetError() << "\n"; << Mix_GetError() << "\n";
return false; return false;
} }
sound_cache.push_front(temp_chunk); sound_cache.push_front(temp_chunk);
it = sound_cache.begin(); 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 // Play sound, or random one of comma-separated sounds. Use specified
// distance and associate it with specified id (of a sound source). // 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 // Play sound, or random one of comma-separated sounds in bell channel
void play_bell(const std::string& files); void play_bell(const std::string& files);

View File

@ -37,7 +37,7 @@ namespace soundsource {
unsigned int manager::positional_source::last_id = 0; 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); _disp.scroll_event().attach_handler(this);
update_positions(); update_positions();
@ -58,16 +58,16 @@ void manager::handle_generic_event(const std::string &event_name)
update_positions(); 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; positional_source_iterator it;
if((it = _sources.find(id)) == _sources.end()) { 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 { else {
delete (*it).second; 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) 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), : _last_played(0), _min_delay(min_delay), _chance(chance), _loop(loop),
_id(last_id++), _play_fogged(play_fogged), _visible(false), _id(last_id++), _play_fogged(play_fogged), _visible(false),
_files(files) _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 // If no locations have been specified, treat the source as if
// it was present everywhere on the map // it was present everywhere on the map
if(_locations.size() == 0) { 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; return;
} }
@ -152,8 +152,9 @@ void manager::positional_source::update(unsigned int time, const display &disp)
/* }*/ /* }*/
} }
if(!sound::is_sound_playing(last_id)) if(!sound::is_sound_playing(last_id)) {
sound::play_sound_positioned(_files, last_id, distance_volume); 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 _last_played;
unsigned int _min_delay; unsigned int _min_delay;
unsigned int _chance; unsigned int _chance;
unsigned int _loop;
unsigned int _id; unsigned int _id;
bool _play_fogged; bool _play_fogged;
bool _visible; bool _visible;
@ -53,7 +54,7 @@ class manager : public events::observer {
// chance is a chance ;-) (in %) that the sound source will emit // chance is a chance ;-) (in %) that the sound source will emit
// sound every second after the delay has passed or once the source // sound every second after the delay has passed or once the source
// becomes visible // 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(unsigned int time, const display &disp);
void update_positions(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); void handle_generic_event(const std::string &event_name);
// add or replace a soundsource // 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 remove(const std::string &id);
void update(); void update();