X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Flibgame%2Fsound.c;h=4f5ddd0b2ca46fd741863cf36d9fa3d00b259ade;hp=591ea7d444ce3ecbe416fe96cbcc2b39c5a03ef6;hb=b641818c787e48bbf03ce2a0cd5b542c4c21e523;hpb=3ff2e8a0b5c27b99a9920bdf5ed82bc41bf40181 diff --git a/src/libgame/sound.c b/src/libgame/sound.c index 591ea7d4..4f5ddd0b 100644 --- a/src/libgame/sound.c +++ b/src/libgame/sound.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // sound.c // ============================================================================ @@ -27,10 +27,10 @@ #include "text.h" -/* expiration time (in milliseconds) for sound loops */ +// expiration time (in milliseconds) for sound loops #define SOUND_LOOP_EXPIRATION_TIME 200 -/* one second fading interval == 1000 ticks (milliseconds) */ +// one second fading interval == 1000 ticks (milliseconds) #define SOUND_FADING_INTERVAL 1000 #define SND_TYPE_NONE 0 @@ -59,18 +59,18 @@ #define SOUND_VOLUME_LOOPS(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_loops) #define SOUND_VOLUME_MUSIC(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_music) -#define SETUP_SOUND_VOLUME(v,s) ((s) == SND_CTRL_PLAY_MUSIC ? \ +#define SETUP_SOUND_VOLUME(v,s) ((s) & SND_CTRL_MUSIC ? \ SOUND_VOLUME_MUSIC(v) : \ - (s) == SND_CTRL_PLAY_LOOP ? \ + (s) & SND_CTRL_LOOP ? \ SOUND_VOLUME_LOOPS(v) : \ SOUND_VOLUME_SIMPLE(v)) struct AudioFormatInfo { - boolean stereo; /* availability of stereo sound */ - int format; /* size and endianess of sample data */ - int sample_rate; /* sample frequency */ - int fragment_size; /* audio device fragment size in bytes */ + boolean stereo; // availability of stereo sound + int format; // size and endianess of sample data + int sample_rate; // sample frequency + int fragment_size; // audio device fragment size in bytes }; struct SampleInfo @@ -80,9 +80,9 @@ struct SampleInfo int type; int format; - void *data_ptr; /* pointer to first sample (8 or 16 bit) */ - int data_len; /* number of samples, NOT number of bytes */ - int num_channels; /* mono: 1 channel, stereo: 2 channels */ + void *data_ptr; // pointer to first sample (8 or 16 bit) + int data_len; // number of samples, NOT number of bytes + int num_channels; // mono: 1 channel, stereo: 2 channels }; typedef struct SampleInfo SoundInfo; typedef struct SampleInfo MusicInfo; @@ -102,9 +102,9 @@ struct SoundControl int type; int format; - void *data_ptr; /* pointer to first sample (8 or 16 bit) */ - int data_len; /* number of samples, NOT number of bytes */ - int num_channels; /* mono: 1 channel, stereo: 2 channels */ + void *data_ptr; // pointer to first sample (8 or 16 bit) + int data_len; // number of samples, NOT number of bytes + int num_channels; // mono: 1 channel, stereo: 2 channels }; typedef struct SoundControl SoundControl; @@ -116,28 +116,32 @@ static MusicInfo **Music_NoConf = NULL; static int num_music_noconf = 0; static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1]; +static char *currently_playing_music_filename = NULL; -/* ========================================================================= */ -/* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */ + +// ============================================================================ +// THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS static struct SoundControl mixer[NUM_MIXER_CHANNELS]; static int mixer_active_channels = 0; +static boolean expire_loop_sounds = FALSE; -static void ReloadCustomSounds(); -static void ReloadCustomMusic(); +static void ReloadCustomSounds(void); +static void ReloadCustomMusic(void); static void FreeSound(void *); static void FreeMusic(void *); -static void FreeAllMusic_NoConf(); +static void FreeAllMusic_NoConf(void); +static void Mixer_StopMusicChannel(void); static SoundInfo *getSoundInfoEntryFromSoundID(int); static MusicInfo *getMusicInfoEntryFromMusicID(int); -/* ------------------------------------------------------------------------- */ -/* mixer functions */ -/* ------------------------------------------------------------------------- */ +// ---------------------------------------------------------------------------- +// mixer functions +// ---------------------------------------------------------------------------- -void Mixer_InitChannels() +void Mixer_InitChannels(void) { int i; @@ -150,7 +154,8 @@ static void Mixer_ResetChannelExpiration(int channel) { mixer[channel].playing_starttime = Counter(); - if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel])) + if (expire_loop_sounds && + IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel])) Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME); } @@ -159,7 +164,8 @@ static boolean Mixer_ChannelExpired(int channel) if (!mixer[channel].active) return TRUE; - if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) && + if (expire_loop_sounds && + IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) && DelayReached(&mixer[channel].playing_starttime, SOUND_LOOP_EXPIRATION_TIME)) return TRUE; @@ -191,7 +197,7 @@ static void Mixer_StartChannel(int channel) static void Mixer_PlayChannel(int channel) { - /* start with inactive channel in case something goes wrong */ + // start with inactive channel in case something goes wrong mixer[channel].active = FALSE; if (mixer[channel].type != MUS_TYPE_WAV) @@ -210,16 +216,32 @@ static void Mixer_PlayChannel(int channel) mixer_active_channels++; } -static void Mixer_PlayMusicChannel() +static void Mixer_PlayMusicChannel(void) { Mixer_PlayChannel(audio.music_channel); if (mixer[audio.music_channel].type != MUS_TYPE_WAV) { - /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() -- - this looks like a bug in the SDL_mixer library */ - Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1); + int loops = (IS_LOOP(mixer[audio.music_channel]) ? -1 : 1); + + // stopping music channel before playing next track seems to be needed to + // prevent audio problems that may occur when playing MP3 files on Windows + Mixer_StopMusicChannel(); + + // use short fade-in to prevent "plop" sound for certain music files + // (this may happen when switching on music while playing the game) Mix_VolumeMusic(mixer[audio.music_channel].volume); + Mix_FadeInMusic(mixer[audio.music_channel].data_ptr, loops, 100); + +#if defined(PLATFORM_WIN32) + // playing MIDI music is broken since Windows Vista, as it sets the volume + // for MIDI music also for all other sounds and music, which cannot be set + // back to normal unless playing MIDI music again with that desired volume + // (more details: https://www.artsoft.org/forum/viewtopic.php?f=7&t=2253) + // => workaround: always play MIDI music with maximum volume + if (Mix_GetMusicType(NULL) == MUS_MID) + Mix_VolumeMusic(SOUND_MAX_VOLUME); +#endif } } @@ -234,11 +256,13 @@ static void Mixer_StopChannel(int channel) mixer_active_channels--; } -static void Mixer_StopMusicChannel() +static void Mixer_StopMusicChannel(void) { Mixer_StopChannel(audio.music_channel); Mix_HaltMusic(); + + setString(¤tly_playing_music_filename, NULL); } static void Mixer_FadeChannel(int channel) @@ -251,11 +275,23 @@ static void Mixer_FadeChannel(int channel) Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL); } -static void Mixer_FadeMusicChannel() +static void Mixer_FadeMusicChannel(void) { Mixer_FadeChannel(audio.music_channel); Mix_FadeOutMusic(SOUND_FADING_INTERVAL); + +#if defined(PLATFORM_WIN32) + // playing MIDI music is broken since Windows Vista, as it sets the volume + // for MIDI music also for all other sounds and music, which cannot be set + // back to normal unless playing MIDI music again with that desired volume + // (more details: https://www.artsoft.org/forum/viewtopic.php?f=7&t=2253) + // => workaround: never fade MIDI music to lower volume, but just stop it + if (Mix_GetMusicType(NULL) == MUS_MID) + Mixer_StopMusicChannel(); +#endif + + setString(¤tly_playing_music_filename, NULL); } static void Mixer_UnFadeChannel(int channel) @@ -274,44 +310,23 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) { SoundInfo *snd_info; int i, k; - int num_sounds = getSoundListSize(); - int num_music = getMusicListSize(); if (IS_MUSIC(snd_ctrl)) - { - if (snd_ctrl.nr >= num_music) /* invalid music */ - return; - - if (snd_ctrl.nr < 0) /* undefined music */ - { - if (num_music_noconf == 0) /* no fallback music available */ - return; - - snd_ctrl.nr = UNMAP_NOCONF_MUSIC(snd_ctrl.nr) % num_music_noconf; - snd_info = Music_NoConf[snd_ctrl.nr]; - } - else - snd_info = getMusicInfoEntryFromMusicID(snd_ctrl.nr); - } + snd_info = getMusicInfoEntryFromMusicID(snd_ctrl.nr); else - { - if (snd_ctrl.nr < 0 || snd_ctrl.nr >= num_sounds) - return; - snd_info = getSoundInfoEntryFromSoundID(snd_ctrl.nr); - } if (snd_info == NULL) return; - /* copy sound sample and format information */ + // copy sound sample and format information snd_ctrl.type = snd_info->type; snd_ctrl.format = snd_info->format; snd_ctrl.data_ptr = snd_info->data_ptr; snd_ctrl.data_len = snd_info->data_len; snd_ctrl.num_channels = snd_info->num_channels; - /* play music samples on a dedicated music channel */ + // play music samples on a dedicated music channel if (IS_MUSIC(snd_ctrl)) { Mixer_StopMusicChannel(); @@ -319,15 +334,18 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) mixer[audio.music_channel] = snd_ctrl; Mixer_PlayMusicChannel(); + setString(¤tly_playing_music_filename, + getBaseNamePtr(snd_info->source_filename)); + return; } - /* check if (and how often) this sound sample is already playing */ + // check if (and how often) this sound sample is already playing for (k = 0, i = audio.first_sound_channel; i < audio.num_channels; i++) if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl)) k++; - /* reset expiration delay for already playing loop sounds */ + // reset expiration delay for already playing loop sounds if (k > 0 && IS_LOOP(snd_ctrl)) { for (i = audio.first_sound_channel; i < audio.num_channels; i++) @@ -337,7 +355,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) if (IS_FADING(mixer[i])) Mixer_UnFadeChannel(i); - /* restore settings like volume and stereo position */ + // restore settings like volume and stereo position mixer[i].volume = snd_ctrl.volume; mixer[i].stereo_position = snd_ctrl.stereo_position; @@ -349,13 +367,13 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) return; } - /* don't play sound more than n times simultaneously (with n == 2 for now) */ + // don't play sound more than n times simultaneously (with n == 2 for now) if (k >= 2) { unsigned int playing_current = Counter(); int longest = 0, longest_nr = audio.first_sound_channel; - /* look for oldest equal sound */ + // look for oldest equal sound for (i = audio.first_sound_channel; i < audio.num_channels; i++) { int playing_time = playing_current - mixer[i].playing_starttime; @@ -383,7 +401,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) library, we use the current playing time (in milliseconds) instead. */ #if DEBUG - /* channel allocation sanity check -- should not be needed */ + // channel allocation sanity check -- should not be needed if (mixer_active_channels == audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1)) { @@ -421,7 +439,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) Mixer_StopChannel(longest_nr); } - /* add the new sound to the mixer */ + // add the new sound to the mixer for (i = audio.first_sound_channel; i < audio.num_channels; i++) { if (!mixer[i].active) @@ -438,12 +456,12 @@ static void HandleSoundRequest(SoundControl snd_ctrl) { int i; - /* deactivate channels that have expired since the last request */ + // deactivate channels that have expired since the last request for (i = 0; i < audio.num_channels; i++) if (mixer[i].active && Mixer_ChannelExpired(i)) Mixer_StopChannel(i); - if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */ + if (IS_RELOADING(snd_ctrl)) // load new sound or music files { Mixer_StopMusicChannel(); for (i = audio.first_sound_channel; i < audio.num_channels; i++) @@ -454,7 +472,7 @@ static void HandleSoundRequest(SoundControl snd_ctrl) else ReloadCustomMusic(); } - else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */ + else if (IS_FADING(snd_ctrl)) // fade out existing sound or music { if (IS_MUSIC(snd_ctrl)) { @@ -466,7 +484,7 @@ static void HandleSoundRequest(SoundControl snd_ctrl) if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl)) Mixer_FadeChannel(i); } - else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */ + else if (IS_STOPPING(snd_ctrl)) // stop existing sound or music { if (IS_MUSIC(snd_ctrl)) { @@ -478,7 +496,11 @@ static void HandleSoundRequest(SoundControl snd_ctrl) if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl)) Mixer_StopChannel(i); } - else if (snd_ctrl.active) /* add new sound to mixer */ + else if (SET_EXPIRE_LOOPS(snd_ctrl)) // set loop expiration on or off + { + expire_loop_sounds = snd_ctrl.active; + } + else if (snd_ctrl.active) // add new sound to mixer { Mixer_InsertSound(snd_ctrl); } @@ -491,19 +513,19 @@ void StartMixer(void) if (!audio.sound_available) return; - /* initialize stereo position conversion information */ + // initialize stereo position conversion information for (i = 0; i <= SOUND_MAX_LEFT2RIGHT; i++) stereo_volume[i] = (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i)); } -/* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */ -/* ========================================================================= */ -/* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */ +// THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS +// ============================================================================ +// THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS -#define CHUNK_ID_LEN 4 /* IFF style chunk id length */ -#define WAV_HEADER_SIZE 16 /* size of WAV file header */ +#define CHUNK_ID_LEN 4 // IFF style chunk id length +#define WAV_HEADER_SIZE 16 // size of WAV file header static void *Load_WAV(char *filename) { @@ -516,7 +538,7 @@ static void *Load_WAV(char *filename) if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL) { - Error(ERR_WARN, "cannot read sound file '%s'", filename); + Error(ERR_WARN, "cannot read sound file '%s': %s", filename, Mix_GetError()); free(snd_info); return NULL; } @@ -540,7 +562,7 @@ static void *Load_MOD(char *filename) if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL) { - Error(ERR_WARN, "cannot read music file '%s'", filename); + Error(ERR_WARN, "cannot read music file '%s': %s", filename, Mix_GetError()); free(mod_info); return NULL; } @@ -561,9 +583,9 @@ static void *Load_WAV_or_MOD(char *filename) return NULL; } -void LoadCustomMusic_NoConf(void) +static void LoadCustomMusic_NoConf(void) { - static boolean draw_init_text = TRUE; /* only draw at startup */ + static boolean draw_init_text = TRUE; // only draw at startup static char *last_music_directory = NULL; char *music_directory = getCustomMusicDirectory(); Directory *dir; @@ -575,7 +597,7 @@ void LoadCustomMusic_NoConf(void) if (last_music_directory != NULL && strEqual(last_music_directory, music_directory)) - return; /* old and new music directory are the same */ + return; // old and new music directory are the same if (last_music_directory != NULL) free(last_music_directory); @@ -595,15 +617,14 @@ void LoadCustomMusic_NoConf(void) if (draw_init_text) DrawInitText("Loading music", 120, FC_GREEN); - while ((dir_entry = readDirectory(dir)) != NULL) /* loop all entries */ + while ((dir_entry = readDirectory(dir)) != NULL) // loop all entries { char *basename = dir_entry->basename; - char *filename = NULL; MusicInfo *mus_info = NULL; boolean music_already_used = FALSE; int i; - /* skip all music files that are configured in music config file */ + // skip all music files that are configured in music config file for (i = 0; i < num_music; i++) { struct FileInfo *music = getMusicListEntry(i); @@ -621,12 +642,8 @@ void LoadCustomMusic_NoConf(void) if (draw_init_text) DrawInitText(basename, 150, FC_YELLOW); - filename = getPath2(music_directory, basename); - - if (FileIsMusic(basename)) - mus_info = Load_WAV_or_MOD(filename); - - free(filename); + if (FileIsMusic(dir_entry->filename)) + mus_info = Load_WAV_or_MOD(dir_entry->filename); if (mus_info) { @@ -642,13 +659,13 @@ void LoadCustomMusic_NoConf(void) draw_init_text = FALSE; } -int getSoundListSize() +int getSoundListSize(void) { return (sound_info->num_file_list_entries + sound_info->num_dynamic_file_list_entries); } -int getMusicListSize() +int getMusicListSize(void) { return (music_info->num_file_list_entries + music_info->num_dynamic_file_list_entries); @@ -656,60 +673,101 @@ int getMusicListSize() struct FileInfo *getSoundListEntry(int pos) { + int num_sounds = getSoundListSize(); int num_list_entries = sound_info->num_file_list_entries; int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries); + if (pos < 0 || pos >= num_sounds) // invalid sound + return NULL; + return (pos < num_list_entries ? &sound_info->file_list[list_pos] : &sound_info->dynamic_file_list[list_pos]); } struct FileInfo *getMusicListEntry(int pos) { + int num_music = getMusicListSize(); int num_list_entries = music_info->num_file_list_entries; int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries); + if (pos < 0 || pos >= num_music) // invalid music + return NULL; + return (pos < num_list_entries ? &music_info->file_list[list_pos] : &music_info->dynamic_file_list[list_pos]); } static SoundInfo *getSoundInfoEntryFromSoundID(int pos) { + int num_sounds = getSoundListSize(); int num_list_entries = sound_info->num_file_list_entries; int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries); SoundInfo **snd_info = (SoundInfo **)(pos < num_list_entries ? sound_info->artwork_list : sound_info->dynamic_artwork_list); + if (pos < 0 || pos >= num_sounds) // invalid sound + return NULL; + return snd_info[list_pos]; } static MusicInfo *getMusicInfoEntryFromMusicID(int pos) { + int num_music = getMusicListSize(); int num_list_entries = music_info->num_file_list_entries; int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries); MusicInfo **mus_info = (MusicInfo **)(pos < num_list_entries ? music_info->artwork_list : music_info->dynamic_artwork_list); + if (pos >= num_music) // invalid music + return NULL; + + if (pos < 0) // undefined music + { + if (num_music_noconf == 0) // no fallback music available + return NULL; + + pos = UNMAP_NOCONF_MUSIC(pos) % num_music_noconf; + + return Music_NoConf[pos]; + } + return mus_info[list_pos]; } -int getSoundListPropertyMappingSize() +char *getMusicInfoEntryFilename(int pos) +{ + MusicInfo *mus_info = getMusicInfoEntryFromMusicID(pos); + + if (mus_info == NULL) + return NULL; + + return getBaseNamePtr(mus_info->source_filename); +} + +char *getCurrentlyPlayingMusicFilename(void) +{ + return currently_playing_music_filename; +} + +int getSoundListPropertyMappingSize(void) { return sound_info->num_property_mapping_entries; } -int getMusicListPropertyMappingSize() +int getMusicListPropertyMappingSize(void) { return music_info->num_property_mapping_entries; } -struct PropertyMapping *getSoundListPropertyMapping() +struct PropertyMapping *getSoundListPropertyMapping(void) { return sound_info->property_mapping; } -struct PropertyMapping *getMusicListPropertyMapping() +struct PropertyMapping *getMusicListPropertyMapping(void) { return music_info->property_mapping; } @@ -725,7 +783,7 @@ void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries, sound_info = checked_calloc(sizeof(struct ArtworkListInfo)); sound_info->type = ARTWORK_TYPE_SOUNDS; - /* ---------- initialize file list and suffix lists ---------- */ + // ---------- initialize file list and suffix lists ---------- sound_info->num_file_list_entries = num_file_list_entries; sound_info->num_dynamic_file_list_entries = 0; @@ -741,7 +799,7 @@ void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries, sound_info->suffix_list = config_suffix_list; - /* ---------- initialize base prefix and suffixes lists ---------- */ + // ---------- initialize base prefix and suffixes lists ---------- sound_info->num_base_prefixes = 0; for (i = 0; base_prefixes[i] != NULL; i++) @@ -773,7 +831,7 @@ void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries, sound_info->property_mapping = NULL; - /* ---------- initialize artwork reference and content lists ---------- */ + // ---------- initialize artwork reference and content lists ---------- sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *); @@ -783,7 +841,7 @@ void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries, sound_info->content_list = NULL; - /* ---------- initialize artwork loading/freeing functions ---------- */ + // ---------- initialize artwork loading/freeing functions ---------- sound_info->load_artwork = Load_WAV; sound_info->free_artwork = FreeSound; @@ -800,7 +858,7 @@ void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries, music_info = checked_calloc(sizeof(struct ArtworkListInfo)); music_info->type = ARTWORK_TYPE_MUSIC; - /* ---------- initialize file list and suffix lists ---------- */ + // ---------- initialize file list and suffix lists ---------- music_info->num_file_list_entries = num_file_list_entries; music_info->num_dynamic_file_list_entries = 0; @@ -816,7 +874,7 @@ void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries, music_info->suffix_list = config_suffix_list; - /* ---------- initialize base prefix and suffixes lists ---------- */ + // ---------- initialize base prefix and suffixes lists ---------- music_info->num_base_prefixes = 0; for (i = 0; base_prefixes[i] != NULL; i++) @@ -848,7 +906,7 @@ void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries, music_info->property_mapping = NULL; - /* ---------- initialize artwork reference and content lists ---------- */ + // ---------- initialize artwork reference and content lists ---------- music_info->sizeof_artwork_list_entry = sizeof(MusicInfo *); @@ -858,7 +916,7 @@ void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries, music_info->content_list = NULL; - /* ---------- initialize artwork loading/freeing functions ---------- */ + // ---------- initialize artwork loading/freeing functions ---------- music_info->load_artwork = Load_WAV_or_MOD; music_info->free_artwork = FreeMusic; @@ -872,6 +930,14 @@ void PlayMusic(int nr) PlaySoundMusic(nr); } +void PlayMusicLoop(int nr) +{ + if (!audio.music_available) + return; + + PlaySoundMusicLoop(nr); +} + void PlaySound(int nr) { if (!setup.sound_simple) @@ -904,6 +970,14 @@ void PlaySoundMusic(int nr) PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC); } +void PlaySoundMusicLoop(int nr) +{ + if (!setup.sound_music) + return; + + PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC_LOOP); +} + void PlaySoundExt(int nr, int volume, int stereo_position, int state) { SoundControl snd_ctrl; @@ -925,7 +999,7 @@ void PlaySoundExt(int nr, int volume, int stereo_position, int state) else if (stereo_position > SOUND_MAX_RIGHT) stereo_position = SOUND_MAX_RIGHT; - clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */ + clear_mem(&snd_ctrl, sizeof(SoundControl)); // to make valgrind happy snd_ctrl.active = TRUE; snd_ctrl.nr = nr; @@ -949,12 +1023,12 @@ void FadeSound(int nr) StopSoundExt(nr, SND_CTRL_FADE_SOUND); } -void FadeSounds() +void FadeSounds(void) { StopSoundExt(-1, SND_CTRL_FADE_ALL); } -void FadeSoundsAndMusic() +void FadeSoundsAndMusic(void) { FadeSounds(); FadeMusic(); @@ -973,7 +1047,7 @@ void StopSound(int nr) StopSoundExt(nr, SND_CTRL_STOP_SOUND); } -void StopSounds() +void StopSounds(void) { StopMusic(); StopSoundExt(-1, SND_CTRL_STOP_ALL); @@ -986,7 +1060,7 @@ void StopSoundExt(int nr, int state) if (!audio.sound_available) return; - clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */ + clear_mem(&snd_ctrl, sizeof(SoundControl)); // to make valgrind happy snd_ctrl.active = FALSE; snd_ctrl.nr = nr; @@ -995,18 +1069,33 @@ void StopSoundExt(int nr, int state) HandleSoundRequest(snd_ctrl); } -static void ReloadCustomSounds() +void ExpireSoundLoops(boolean active) +{ + SoundControl snd_ctrl; + + if (!audio.sound_available) + return; + + clear_mem(&snd_ctrl, sizeof(SoundControl)); // to make valgrind happy + + snd_ctrl.active = active; + snd_ctrl.state = SND_CTRL_EXPIRE_LOOPS; + + HandleSoundRequest(snd_ctrl); +} + +static void ReloadCustomSounds(void) { LoadArtworkConfig(sound_info); ReloadCustomArtworkList(sound_info); } -static void ReloadCustomMusic() +static void ReloadCustomMusic(void) { LoadArtworkConfig(music_info); ReloadCustomArtworkList(music_info); - /* load all music files from directory not defined in "musicinfo.conf" */ + // load all music files from directory not defined in "musicinfo.conf" LoadCustomMusic_NoConf(); } @@ -1061,7 +1150,7 @@ void FreeMusic(void *ptr) free(music); } -static void FreeAllMusic_NoConf() +static void FreeAllMusic_NoConf(void) { int i; @@ -1077,16 +1166,16 @@ static void FreeAllMusic_NoConf() num_music_noconf = 0; } -void FreeAllSounds() +void FreeAllSounds(void) { FreeCustomArtworkLists(sound_info); } -void FreeAllMusic() +void FreeAllMusic(void) { FreeCustomArtworkLists(music_info); FreeAllMusic_NoConf(); } -/* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */ -/* ========================================================================= */ +// THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS +// ============================================================================