rnd-20020803-1-src
[rocksndiamonds.git] / src / libgame / sound.c
index b29d5dd62616a3dc9b1f245b2cb83707b9cf6397..cd34b284473e3126a0191fc3074f7005793fd0e0 100644 (file)
@@ -1,7 +1,7 @@
 /***********************************************************
 * Artsoft Retro-Game Library                               *
 *----------------------------------------------------------*
-* (c) 1994-2001 Artsoft Entertainment                      *
+* (c) 1994-2002 Artsoft Entertainment                      *
 *               Holger Schemel                             *
 *               Detmolder Strasse 189                      *
 *               33604 Bielefeld                            *
@@ -11,8 +11,9 @@
 * sound.c                                                  *
 ***********************************************************/
 
-#include <string.h>
+#include <sys/types.h>
 #include <sys/time.h>
+#include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <dirent.h>
@@ -71,6 +72,8 @@
 #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)
 
 #if 0
 struct SoundHeader_SUN
@@ -495,6 +498,9 @@ static void WriteReloadInfoToPipe(char *set_name, int type)
   unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
   unsigned long str_size2 = strlen(ti->basepath) + 1;
   unsigned long str_size3 = strlen(ti->fullpath) + 1;
+  boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
+                                   setup.override_level_sounds :
+                                   setup.override_level_music);
 
   if (IS_CHILD_PROCESS(audio.mixer_pid))
     return;
@@ -510,6 +516,8 @@ static void WriteReloadInfoToPipe(char *set_name, int type)
            sizeof(snd_ctrl)) < 0 ||
       write(audio.mixer_pipe[1], set_name,
            snd_ctrl.data_len) < 0 ||
+      write(audio.mixer_pipe[1], &override_level_artwork,
+           sizeof(boolean)) < 0 ||
       write(audio.mixer_pipe[1], leveldir_current,
            sizeof(TreeInfo)) < 0 ||
       write(audio.mixer_pipe[1], ti,
@@ -540,6 +548,9 @@ static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
   TreeInfo *ti = *ti_ptr;
   unsigned long str_size1, str_size2, str_size3;
   static char *set_name = NULL;
+  boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
+                                    &setup.override_level_sounds :
+                                    &setup.override_level_music);
 
   if (set_name)
     free(set_name);
@@ -559,6 +570,8 @@ static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
 
   if (read(audio.mixer_pipe[0], set_name,
           snd_ctrl->data_len) != snd_ctrl->data_len ||
+      read(audio.mixer_pipe[0], override_level_artwork,
+          sizeof(boolean)) != sizeof(boolean) ||
       read(audio.mixer_pipe[0], leveldir_current,
           sizeof(TreeInfo)) != sizeof(TreeInfo) ||
       read(audio.mixer_pipe[0], ti,
@@ -584,9 +597,9 @@ static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
     Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
 
   if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
-    artwork.sounds_set_current = set_name;
+    artwork.sounds_set_current_name = set_name;
   else
-    artwork.music_set_current = set_name;
+    artwork.music_set_current_name = set_name;
 }
 
 #endif /* AUDIO_UNIX_NATIVE */
@@ -798,7 +811,12 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
 #endif
 
   if (IS_MUSIC(snd_ctrl))
+  {
+    if (num_music == 0)
+      return;
+
     snd_ctrl.nr = snd_ctrl.nr % num_music;
+  }
   else if (snd_ctrl.nr >= num_sounds)
     return;
 
@@ -826,9 +844,9 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
     return;
   }
 
-  /* check if sound is already being played (and how often) */
+  /* 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 && mixer[i].nr == snd_ctrl.nr)
+    if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
       k++;
 
 #if 0
@@ -840,7 +858,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
   {
     for(i=audio.first_sound_channel; i<audio.num_channels; i++)
     {
-      if (mixer[i].active && mixer[i].nr == snd_ctrl.nr)
+      if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
       {
 #if 0
        printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
@@ -866,6 +884,10 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
     return;
   }
 
+#if 0
+  printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr);
+#endif
+
   /* don't play sound more than n times simultaneously (with n == 2 for now) */
   if (k >= 2)
   {
@@ -878,7 +900,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
       int playing_time = playing_current - mixer[i].playing_starttime;
       int actual;
 
-      if (!mixer[i].active || mixer[i].nr != snd_ctrl.nr)
+      if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
        continue;
 
       actual = 1000 * playing_time / mixer[i].data_len;
@@ -1008,7 +1030,7 @@ static void HandleSoundRequest(SoundControl snd_ctrl)
     }
 
     for(i=audio.first_sound_channel; i<audio.num_channels; i++)
-      if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(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 */
@@ -1020,7 +1042,7 @@ static void HandleSoundRequest(SoundControl snd_ctrl)
     }
 
     for(i=audio.first_sound_channel; i<audio.num_channels; i++)
-      if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
+      if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
        Mixer_StopChannel(i);
 
 #if defined(AUDIO_UNIX_NATIVE)
@@ -1283,7 +1305,7 @@ static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
        mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
 
   /* might be needed for u-law /dev/audio */
-#if 0
+#if 1
   for(j=0; j<sample_size; j++)
     playing_buffer[j] =
       linear_to_ulaw(premix_first_buffer[j]);
@@ -1825,6 +1847,7 @@ static MusicInfo *Load_MOD(char *filename)
 void LoadCustomMusic(void)
 {
   static boolean draw_init_text = TRUE;                /* only draw at startup */
+  static char *last_music_directory = NULL;
   char *music_directory = getCustomMusicDirectory();
   DIR *dir;
   struct dirent *dir_entry;
@@ -1832,6 +1855,14 @@ void LoadCustomMusic(void)
   if (!audio.sound_available)
     return;
 
+  if (last_music_directory != NULL &&
+      strcmp(last_music_directory, music_directory) == 0)
+    return;    /* old and new music directory are the same */
+
+  last_music_directory = music_directory;
+
+  FreeAllMusic();
+
   if ((dir = opendir(music_directory)) == NULL)
   {
     Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
@@ -2102,7 +2133,7 @@ static void ReloadCustomSounds()
   int i;
 
 #if 0
-  printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
+  printf("DEBUG: reloading sounds '%s' ...\n",artwork.sounds_set_current_name);
 #endif
 
   LoadSoundsInfo();
@@ -2139,10 +2170,13 @@ static void ReloadCustomSounds()
 static void ReloadCustomMusic()
 {
 #if 0
-  printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
+  printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current_name);
 #endif
 
+#if 0
+  /* this is done directly in LoadCustomMusic() now */
   FreeAllMusic();
+#endif
 
   LoadCustomMusic();
 }