rnd-20020428-3-src
[rocksndiamonds.git] / src / libgame / sound.c
index 20a1978ee4465d7e108d96c84a90a2cc8bacb9ec..61644cda859874bddb68ce813da558ddb0174aa6 100644 (file)
@@ -27,6 +27,7 @@
 static SoundInfo **Sound = NULL;
 static MusicInfo **Music = NULL;
 static int num_sounds = 0, num_music = 0;
+static char **sound_name;
 
 
 /* ========================================================================= */
@@ -70,6 +71,10 @@ static void SoundServer_StopSound(struct SoundControl);
 static void SoundServer_StopAllSounds();
 #endif
 
+static void ReloadCustomSounds();
+static void ReloadCustomMusic();
+static void FreeSound(SoundInfo *);
+
 #if defined(PLATFORM_UNIX)
 static int OpenAudioDevice(char *audio_device_name)
 {
@@ -277,12 +282,18 @@ void SoundServer(void)
       if (snd_ctrl.reload_sounds)
       {
        artwork.sounds_set_current = set_name;
+       ReloadCustomSounds();
+#if 0
        audio.func_reload_sounds();
+#endif
       }
       else
       {
        artwork.music_set_current = set_name;
+       ReloadCustomMusic();
+#if 0
        audio.func_reload_music();
+#endif
       }
 
       free(set_name);
@@ -357,8 +368,6 @@ void SoundServer(void)
               select(audio.soundserver_pipe[0] + 1,
                      &sound_fdset, NULL, NULL, &delay) < 1)
        {       
-         void *sample_ptr;
-         int sample_size;
          int max_sample_size;
          int fragment_size = afmt.fragment_size;
          int sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
@@ -374,66 +383,52 @@ void SoundServer(void)
 
          for(i=0; i<MAX_SOUNDS_PLAYING; i++)
          {
+           void *sample_ptr;
+           int sample_len;
+           int sample_pos;
+           int sample_size;
            int j;
 
            if (!playlist[i].active)
              continue;
 
-           /* get pointer and size of the actual sound sample */
-           if (playlist[i].format == AUDIO_FORMAT_U8)
-             sample_ptr =
-               (byte *)playlist[i].data_ptr + playlist[i].playingpos;
-           else
-             sample_ptr =
-               (short *)playlist[i].data_ptr + playlist[i].playingpos;
-
-           sample_size = MIN(max_sample_size,
-                             playlist[i].data_len - playlist[i].playingpos);
+           /* pointer, lenght and actual playing position of sound sample */
+           sample_ptr = playlist[i].data_ptr;
+           sample_len = playlist[i].data_len;
+           sample_pos = playlist[i].playingpos;
+           sample_size = MIN(max_sample_size, sample_len - sample_pos);
            playlist[i].playingpos += sample_size;
 
-           /* fill the first mixing buffer with original sample */
-#if 1
+           /* copy original sample to first mixing buffer */
            if (playlist[i].format == AUDIO_FORMAT_U8)
              for (j=0; j<sample_size; j++)
                premix_first_buffer[j] =
-                 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
-           else
+                 ((short)(((byte *)sample_ptr)[sample_pos + j] ^ 0x80)) << 8;
+           else        /* AUDIO_FORMAT_S16 */
              for (j=0; j<sample_size; j++)
-               premix_first_buffer[j] = ((short *)sample_ptr)[j];
-#else
-           memcpy(premix_first_buffer, sample_ptr,
-                  sample_size * (playlist[i].format == AUDIO_FORMAT_U8 ?
-                                 sizeof(byte) : sizeof(short)));
-#endif
+               premix_first_buffer[j] =
+                 ((short *)sample_ptr)[sample_pos + j];
 
            /* are we about to restart a looping sound? */
            if (playlist[i].loop && sample_size < max_sample_size)
            {
-#if 1
              while (sample_size < max_sample_size)
              {
                int restarted_sample_size =
-                 MIN(max_sample_size - sample_size, playlist[i].data_len);
+                 MIN(max_sample_size - sample_size, sample_len);
 
                if (playlist[i].format == AUDIO_FORMAT_U8)
                  for (j=0; j<restarted_sample_size; j++)
                    premix_first_buffer[sample_size + j] =
-                     ((short)(((byte *)playlist[i].data_ptr)[j] ^ 0x80)) << 8;
+                     ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
                else
                  for (j=0; j<restarted_sample_size; j++)
                    premix_first_buffer[sample_size + j] =
-                     ((short *)playlist[i].data_ptr)[j];
+                     ((short *)sample_ptr)[j];
 
                playlist[i].playingpos = restarted_sample_size;
                sample_size += restarted_sample_size;
              }
-#else
-             playlist[i].playingpos = max_sample_size - sample_size;
-             memcpy(premix_first_buffer + sample_size * sizeof(short),
-                    playlist[i].data_ptr,
-                    (max_sample_size - sample_size) * sizeof(short));
-             sample_size = max_sample_size;
-#endif
            }
 
            /* decrease volume if sound is fading out */
@@ -1109,7 +1104,6 @@ static SoundInfo *Load_WAV(char *filename)
   byte sound_header_buffer[WAV_HEADER_SIZE];
   char chunk_name[CHUNK_ID_LEN + 1];
   int chunk_size;
-  short *data_ptr;
   FILE *file;
   int i;
 #endif
@@ -1117,6 +1111,10 @@ static SoundInfo *Load_WAV(char *filename)
   if (!audio.sound_available)
     return NULL;
 
+#if 1
+  printf("loading WAV file '%s'\n", filename);
+#endif
+
   snd_info = checked_calloc(sizeof(SoundInfo));
 
 #if defined(TARGET_SDL)
@@ -1210,24 +1208,7 @@ static SoundInfo *Load_WAV(char *filename)
     return NULL;
   }
 
-  if (0)
-  {
-    /* convert unsigned 8 bit sample data to signed 16 bit sample data */
-
-    data_ptr = checked_malloc(snd_info->data_len * sizeof(short));
-
-    for (i=0; i<snd_info->data_len; i++)
-      data_ptr[i] = ((short)(((byte *)snd_info->data_ptr)[i] ^ 0x80)) << 8;
-
-    free(snd_info->data_ptr);
-    snd_info->data_ptr = data_ptr;
-
-    snd_info->format = AUDIO_FORMAT_S16;
-  }
-  else
-  {
-    snd_info->format = AUDIO_FORMAT_U8;
-  }
+  snd_info->format = AUDIO_FORMAT_U8;
 
 #endif /* PLATFORM_UNIX */
 
@@ -1237,22 +1218,37 @@ static SoundInfo *Load_WAV(char *filename)
   return snd_info;
 }
 
-SoundInfo *LoadCustomSound(char *basename)
+static void LoadCustomSound(SoundInfo **snd_info, char *basename)
 {
   char *filename = getCustomSoundFilename(basename);
 
-  if (filename == NULL)
+  if (filename == NULL)                /* (should never happen) */
   {
     Error(ERR_WARN, "cannot find sound file '%s'", basename);
-    return FALSE;
+    return;
+  }
+
+  if (*snd_info && strcmp(filename, (*snd_info)->source_filename) == 0)
+  {
+    /* The old and new sound are the same (have the same filename and path).
+       This usually means that this sound does not exist in this sound set
+       and a fallback to the existing sound is done. */
+
+    return;
   }
 
-  return Load_WAV(filename);
+  if (*snd_info)
+    FreeSound(*snd_info);
+
+  *snd_info = Load_WAV(filename);
 }
 
-void InitSoundList(int num_list_entries)
+void InitSoundList(char *sound_name_list[], int num_list_entries)
 {
-  Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
+  if (Sound == NULL)
+    Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
+
+  sound_name = sound_name_list;
   num_sounds = num_list_entries;
 }
 
@@ -1261,10 +1257,7 @@ void LoadSoundToList(char *basename, int list_pos)
   if (Sound == NULL || list_pos >= num_sounds)
     return;
 
-  if (Sound[list_pos])
-    FreeSound(Sound[list_pos]);
-
-  Sound[list_pos] = LoadCustomSound(basename);
+  LoadCustomSound(&Sound[list_pos], basename);
 }
 
 static MusicInfo *Load_MOD(char *filename)
@@ -1541,6 +1534,31 @@ void StopSoundExt(int nr, int method)
 #endif
 }
 
+static void ReloadCustomSounds()
+{
+  int i;
+
+#if 1
+  printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
+#endif
+
+  LoadSoundsInfo();
+
+  for(i=0; i<num_sounds; i++)
+    LoadSoundToList(sound_name[i], i);
+}
+
+static void ReloadCustomMusic()
+{
+#if 1
+  printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
+#endif
+
+  FreeAllMusic();
+
+  LoadCustomMusic();
+}
+
 static void InitReloadSoundsOrMusic(char *set_name, int type)
 {
 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)