updated contact info in source file headers
[rocksndiamonds.git] / src / libgame / sound.c
index ff42562a19da8ce3249efbfaea7ab9ab6fe3807d..f1c4aaf7fb5e259678d54ac3e4e345edf06e2f69 100644 (file)
@@ -1,15 +1,13 @@
-/***********************************************************
-* Artsoft Retro-Game Library                               *
-*----------------------------------------------------------*
-* (c) 1994-2006 Artsoft Entertainment                      *
-*               Holger Schemel                             *
-*               Detmolder Strasse 189                      *
-*               33604 Bielefeld                            *
-*               Germany                                    *
-*               e-mail: info@artsoft.org                   *
-*----------------------------------------------------------*
-* sound.c                                                  *
-***********************************************************/
+// ============================================================================
+// Artsoft Retro-Game Library
+// ----------------------------------------------------------------------------
+// (c) 1995-2014 by Artsoft Entertainment
+//                         Holger Schemel
+//                 info@artsoft.org
+//                 http://www.artsoft.org/
+// ----------------------------------------------------------------------------
+// sound.c
+// ============================================================================
 
 #include <sys/types.h>
 #include <sys/time.h>
 #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 : \
+                                        (p) > 100 ? (v) :              \
+                                        (p) * (v) / 100)
+
+#define SOUND_VOLUME_SIMPLE(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_simple)
+#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 ?   \
+                                        SOUND_VOLUME_MUSIC(v) :        \
+                                        (s) == SND_CTRL_PLAY_LOOP ?    \
+                                        SOUND_VOLUME_LOOPS(v) :        \
+                                        SOUND_VOLUME_SIMPLE(v))
+
+
 #if defined(AUDIO_UNIX_NATIVE)
 struct SoundHeader_WAV
 {
@@ -123,10 +136,6 @@ struct SoundControl
   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 */
-
-#if defined(TARGET_ALLEGRO)
-  int voice;
-#endif
 };
 typedef struct SoundControl SoundControl;
 
@@ -635,32 +644,15 @@ static boolean Mixer_ChannelExpired(int channel)
     return TRUE;
 
 #if defined(TARGET_SDL)
-
   if (!Mix_Playing(channel))
     return TRUE;
-
-#elif defined(TARGET_ALLEGRO)
-
-  mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
-  mixer[channel].volume = voice_get_volume(mixer[channel].voice);
-
-  /* sound sample has completed playing or was completely faded out */
-  if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
-    return TRUE;
-
-#endif /* TARGET_ALLEGRO */
+#endif
 
   return FALSE;
 }
 
 static boolean Mixer_AllocateChannel(int channel)
 {
-#if defined(TARGET_ALLEGRO)
-  mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
-  if (mixer[channel].voice < 0)
-    return FALSE;
-#endif
-
   return TRUE;
 }
 
@@ -671,9 +663,6 @@ static void Mixer_SetChannelProperties(int channel)
   Mix_SetPanning(channel,
                 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
                 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
-#elif defined(TARGET_ALLEGRO)
-  voice_set_volume(mixer[channel].voice, mixer[channel].volume);
-  voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
 #endif
 }
 
@@ -682,11 +671,6 @@ static void Mixer_StartChannel(int channel)
 #if defined(TARGET_SDL)
   Mix_PlayChannel(channel, mixer[channel].data_ptr,
                  IS_LOOP(mixer[channel]) ? -1 : 0);
-#elif defined(TARGET_ALLEGRO)
-  if (IS_LOOP(mixer[channel]))
-    voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
-
-  voice_start(mixer[channel].voice);       
 #endif
 }
 
@@ -721,7 +705,7 @@ static void Mixer_PlayMusicChannel()
     /* 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);
-    Mix_VolumeMusic(SOUND_MAX_VOLUME);
+    Mix_VolumeMusic(mixer[audio.music_channel].volume);
   }
 #endif
 }
@@ -733,9 +717,6 @@ static void Mixer_StopChannel(int channel)
 
 #if defined(TARGET_SDL)
   Mix_HaltChannel(channel);
-#elif defined(TARGET_ALLEGRO)
-  voice_set_volume(mixer[channel].voice, 0);
-  deallocate_voice(mixer[channel].voice);
 #endif
 
   mixer[channel].active = FALSE;
@@ -760,9 +741,6 @@ static void Mixer_FadeChannel(int channel)
 
 #if defined(TARGET_SDL)
   Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
-#elif defined(TARGET_ALLEGRO)
-  if (voice_check(mixer[channel].voice))
-    voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
 #endif
 }
 
@@ -786,10 +764,6 @@ static void Mixer_UnFadeChannel(int channel)
 #if defined(TARGET_SDL)
   Mix_ExpireChannel(channel, -1);
   Mix_Volume(channel, mixer[channel].volume);
-#elif defined(TARGET_ALLEGRO)
-  voice_stop_volumeramp(mixer[channel].voice);
-  voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
-                   mixer[channel].volume);
 #endif
 }
 
@@ -1548,17 +1522,6 @@ static void *Load_WAV(char *filename)
 
   snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
 
-#elif defined(TARGET_ALLEGRO)
-
-  if ((snd_info->data_ptr = load_sample(filename)) == NULL)
-  {
-    Error(ERR_WARN, "cannot read sound file '%s'", filename);
-    free(snd_info);
-    return NULL;
-  }
-
-  snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
-
 #else /* AUDIO_UNIX_NATIVE */
 
   clear_mem(&header, sizeof(struct SoundHeader_WAV));  /* to make gcc happy */
@@ -1758,14 +1721,108 @@ static void *Load_MOD(char *filename)
 
 static void *Load_WAV_or_MOD(char *filename)
 {
+#if 1
+  if (FileIsMusic(filename))
+    return Load_MOD(filename);
+  else if (FileIsSound(filename))
+    return Load_WAV(filename);
+  else
+    return NULL;
+#else
   if (FileIsSound(filename))
     return Load_WAV(filename);
   else if (FileIsMusic(filename))
     return Load_MOD(filename);
   else
     return NULL;
+#endif
+}
+
+#if 1
+
+void LoadCustomMusic_NoConf(void)
+{
+  static boolean draw_init_text = TRUE;                /* only draw at startup */
+  static char *last_music_directory = NULL;
+  char *music_directory = getCustomMusicDirectory();
+  Directory *dir;
+  DirectoryEntry *dir_entry;
+  int num_music = getMusicListSize();
+
+  if (!audio.sound_available)
+    return;
+
+  if (last_music_directory != NULL &&
+      strEqual(last_music_directory, music_directory))
+    return;    /* old and new music directory are the same */
+
+  if (last_music_directory != NULL)
+    free(last_music_directory);
+  last_music_directory = getStringCopy(music_directory);
+
+  FreeAllMusic_NoConf();
+
+  if ((dir = openDirectory(music_directory)) == NULL)
+  {
+    Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
+
+    audio.music_available = FALSE;
+
+    return;
+  }
+
+  if (draw_init_text)
+    DrawInitText("Loading music", 120, FC_GREEN);
+
+  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 */
+    for (i = 0; i < num_music; i++)
+    {
+      struct FileInfo *music = getMusicListEntry(i);
+
+      if (strEqual(basename, music->filename))
+      {
+       music_already_used = TRUE;
+       break;
+      }
+    }
+
+    if (music_already_used)
+      continue;
+
+    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 (mus_info)
+    {
+      num_music_noconf++;
+      Music_NoConf = checked_realloc(Music_NoConf,
+                                    num_music_noconf * sizeof(MusicInfo *));
+      Music_NoConf[num_music_noconf - 1] = mus_info;
+    }
+  }
+
+  closeDirectory(dir);
+
+  draw_init_text = FALSE;
 }
 
+#else
+
 void LoadCustomMusic_NoConf(void)
 {
   static boolean draw_init_text = TRUE;                /* only draw at startup */
@@ -1791,7 +1848,9 @@ void LoadCustomMusic_NoConf(void)
   if ((dir = opendir(music_directory)) == NULL)
   {
     Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
+
     audio.music_available = FALSE;
+
     return;
   }
 
@@ -1845,6 +1904,8 @@ void LoadCustomMusic_NoConf(void)
   draw_init_text = FALSE;
 }
 
+#endif
+
 int getSoundListSize()
 {
   return (sound_info->num_file_list_entries +
@@ -2077,21 +2138,33 @@ void PlayMusic(int nr)
 
 void PlaySound(int nr)
 {
+  if (!setup.sound_simple)
+    return;
+
   PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
 }
 
 void PlaySoundStereo(int nr, int stereo_position)
 {
+  if (!setup.sound_simple)
+    return;
+
   PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
 }
 
 void PlaySoundLoop(int nr)
 {
+  if (!setup.sound_loops)
+    return;
+
   PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
 }
 
 void PlaySoundMusic(int nr)
 {
+  if (!setup.sound_music)
+    return;
+
   PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
 }
 
@@ -2104,6 +2177,8 @@ void PlaySoundExt(int nr, int volume, int stereo_position, int state)
       audio.sound_deactivated)
     return;
 
+  volume = SETUP_SOUND_VOLUME(volume, state);
+
   if (volume < SOUND_MIN_VOLUME)
     volume = SOUND_MIN_VOLUME;
   else if (volume > SOUND_MAX_VOLUME)
@@ -2244,8 +2319,6 @@ void FreeSound(void *ptr)
   {
 #if defined(TARGET_SDL)
     Mix_FreeChunk(sound->data_ptr);
-#elif defined(TARGET_ALLEGRO)
-    destroy_sample(sound->data_ptr);
 #else /* AUDIO_UNIX_NATIVE */
     free(sound->data_ptr);
 #endif
@@ -2270,8 +2343,6 @@ void FreeMusic(void *ptr)
       Mix_FreeMusic(music->data_ptr);
     else
       Mix_FreeChunk(music->data_ptr);
-#elif defined(TARGET_ALLEGRO)
-    destroy_sample(music->data_ptr);
 #else /* AUDIO_UNIX_NATIVE */
     free(music->data_ptr);
 #endif