added optional button to restart game (door, panel and touch variants)
[rocksndiamonds.git] / src / libgame / sound.c
index 0434b5539c40e61971dc2fe2b80adf1c017b82ad..473850ddaa729d7121aeaaf5873d658703df51e4 100644 (file)
@@ -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
 // ============================================================================
 #define SOUND_VOLUME_LEFT(x)           (stereo_volume[x])
 #define SOUND_VOLUME_RIGHT(x)          (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
 
-#define SAME_SOUND_NR(x,y)             ((x).nr == (y).nr)
-#define SAME_SOUND_DATA(x,y)           ((x).data_ptr == (y).data_ptr)
+#define SAME_SOUND_NR(x, y)            ((x).nr == (y).nr)
+#define SAME_SOUND_DATA(x, y)          ((x).data_ptr == (y).data_ptr)
 
-#define SOUND_VOLUME_FROM_PERCENT(v,p) ((p) < 0   ? SOUND_MIN_VOLUME : \
+#define SOUND_VOLUME_FROM_PERCENT(v, p)        ((p) < 0   ? SOUND_MIN_VOLUME : \
                                         (p) > 100 ? (v) :              \
                                         (p) * (v) / 100)
 
@@ -59,7 +59,7 @@
 #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_MUSIC ?         \
+#define SETUP_SOUND_VOLUME(v, s)       ((s) & SND_CTRL_MUSIC ?         \
                                         SOUND_VOLUME_MUSIC(v) :        \
                                         (s) & SND_CTRL_LOOP ?          \
                                         SOUND_VOLUME_LOOPS(v) :        \
@@ -166,8 +166,8 @@ static boolean Mixer_ChannelExpired(int channel)
 
   if (expire_loop_sounds &&
       IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
-      DelayReached(&mixer[channel].playing_starttime,
-                  SOUND_LOOP_EXPIRATION_TIME))
+      DelayReachedExt2(&mixer[channel].playing_starttime,
+                      SOUND_LOOP_EXPIRATION_TIME, Counter()))
     return TRUE;
 
   if (!Mix_Playing(channel))
@@ -233,7 +233,7 @@ static void Mixer_PlayMusicChannel(void)
     Mix_VolumeMusic(mixer[audio.music_channel].volume);
     Mix_FadeInMusic(mixer[audio.music_channel].data_ptr, loops, 100);
 
-#if defined(PLATFORM_WIN32)
+#if defined(PLATFORM_WINDOWS)
     // 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
@@ -281,7 +281,7 @@ static void Mixer_FadeMusicChannel(void)
 
   Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
 
-#if defined(PLATFORM_WIN32)
+#if defined(PLATFORM_WINDOWS)
   // 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
@@ -409,8 +409,8 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
     {
       if (!mixer[i].active)
       {
-       Error(ERR_INFO, "Mixer_InsertSound: Channel %d inactive", i);
-       Error(ERR_INFO, "Mixer_InsertSound: This should never happen!");
+       Debug("audio", "Mixer_InsertSound: Channel %d inactive", i);
+       Debug("audio", "Mixer_InsertSound: This should never happen!");
 
        mixer_active_channels--;
       }
@@ -538,8 +538,10 @@ static void *Load_WAV(char *filename)
 
   if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
   {
-    Error(ERR_WARN, "cannot read sound file '%s': %s", filename, Mix_GetError());
+    Warn("cannot read sound file '%s': %s", filename, Mix_GetError());
+
     free(snd_info);
+
     return NULL;
   }
 
@@ -562,8 +564,10 @@ static void *Load_MOD(char *filename)
 
   if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
   {
-    Error(ERR_WARN, "cannot read music file '%s': %s", filename, Mix_GetError());
+    Warn("cannot read music file '%s': %s", filename, Mix_GetError());
+
     free(mod_info);
+
     return NULL;
   }
 
@@ -583,11 +587,19 @@ static void *Load_WAV_or_MOD(char *filename)
     return NULL;
 }
 
+static int compareMusicInfo(const void *object1, const void *object2)
+{
+  const MusicInfo *mi1 = *((MusicInfo **)object1);
+  const MusicInfo *mi2 = *((MusicInfo **)object2);
+
+  return strcmp(mi1->source_filename, mi2->source_filename);
+}
+
 static void LoadCustomMusic_NoConf(void)
 {
   static boolean draw_init_text = TRUE;                // only draw at startup
   static char *last_music_directory = NULL;
-  char *music_directory = getCustomMusicDirectory();
+  char *music_directory = getCustomMusicDirectory_NoConf();
   Directory *dir;
   DirectoryEntry *dir_entry;
   int num_music = getMusicListSize();
@@ -605,17 +617,21 @@ static void LoadCustomMusic_NoConf(void)
 
   FreeAllMusic_NoConf();
 
-  if ((dir = openDirectory(music_directory)) == NULL)
+  if (music_directory == NULL)
   {
-    Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
+    Warn("cannot find music directory with unconfigured music");
 
-    audio.music_available = FALSE;
+    return;
+  }
+  else if ((dir = openDirectory(music_directory)) == NULL)
+  {
+    Warn("cannot read music directory '%s'", music_directory);
 
     return;
   }
 
   if (draw_init_text)
-    DrawInitText("Loading music", 120, FC_GREEN);
+    DrawInitTextHead("Loading music");
 
   while ((dir_entry = readDirectory(dir)) != NULL)     // loop all entries
   {
@@ -640,7 +656,7 @@ static void LoadCustomMusic_NoConf(void)
       continue;
 
     if (draw_init_text)
-      DrawInitText(basename, 150, FC_YELLOW);
+      DrawInitTextItem(basename);
 
     if (FileIsMusic(dir_entry->filename))
       mus_info = Load_WAV_or_MOD(dir_entry->filename);
@@ -656,6 +672,9 @@ static void LoadCustomMusic_NoConf(void)
 
   closeDirectory(dir);
 
+  // sort music files by filename
+  qsort(Music_NoConf, num_music_noconf, sizeof(MusicInfo *), compareMusicInfo);
+
   draw_init_text = FALSE;
 }
 
@@ -671,6 +690,11 @@ int getMusicListSize(void)
          music_info->num_dynamic_file_list_entries);
 }
 
+int getMusicListSize_NoConf(void)
+{
+  return num_music_noconf;
+}
+
 struct FileInfo *getSoundListEntry(int pos)
 {
   int num_sounds = getSoundListSize();
@@ -737,6 +761,16 @@ static MusicInfo *getMusicInfoEntryFromMusicID(int pos)
   return mus_info[list_pos];
 }
 
+char *getSoundInfoEntryFilename(int pos)
+{
+  SoundInfo *snd_info = getSoundInfoEntryFromSoundID(pos);
+
+  if (snd_info == NULL)
+    return NULL;
+
+  return getBaseNamePtr(snd_info->source_filename);
+}
+
 char *getMusicInfoEntryFilename(int pos)
 {
   MusicInfo *mus_info = getMusicInfoEntryFromMusicID(pos);
@@ -1099,7 +1133,7 @@ static void ReloadCustomMusic(void)
   LoadCustomMusic_NoConf();
 }
 
-void InitReloadCustomSounds(char *set_identifier)
+void InitReloadCustomSounds(void)
 {
   if (!audio.sound_available)
     return;
@@ -1107,7 +1141,7 @@ void InitReloadCustomSounds(char *set_identifier)
   ReloadCustomSounds();
 }
 
-void InitReloadCustomMusic(char *set_identifier)
+void InitReloadCustomMusic(void)
 {
   if (!audio.music_available)
     return;