+#endif /* PLATFORM_UNIX */
+
+void InitPlaylist(void)
+{
+ int i;
+
+ for(i=0; i<audio.num_channels; i++)
+ playlist[i].active = FALSE;
+ playing_sounds = 0;
+}
+
+static void PlaylistRemoveSound(int pos)
+{
+ if (!playing_sounds || !playlist[pos].active)
+ return;
+
+ playlist[pos].active = FALSE;
+ playing_sounds--;
+}
+
+static void PlaylistInsertSound(struct SoundControl snd_ctrl)
+{
+ SoundInfo *snd_info;
+ int i, k;
+
+#if 0
+ printf("NEW SOUND %d HAS ARRIVED [%d]\n", snd_ctrl.nr, num_sounds);
+#endif
+
+ if (IS_MUSIC(snd_ctrl))
+ snd_ctrl.nr = snd_ctrl.nr % num_music;
+ else if (snd_ctrl.nr >= num_sounds)
+ return;
+
+ snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
+ if (snd_info == NULL)
+ {
+#if 0
+ printf("sound/music %d undefined\n", snd_ctrl.nr);
+#endif
+ return;
+ }
+
+#if 0
+ printf("-> %d\n", playing_sounds);
+#endif
+
+ if (playing_sounds == audio.num_channels)
+ {
+ for (i=0; i<audio.num_channels; i++)
+ {
+ if (playlist[i].data_ptr == NULL)
+ {
+#if 1
+ printf("THIS SHOULD NEVER HAPPEN! [%d]\n", i);
+#endif
+
+ PlaylistRemoveSound(i);
+ }
+ }
+ }
+
+ /* if playlist is full, remove oldest sound */
+ if (playing_sounds == audio.num_channels)
+ {
+ int longest = 0, longest_nr = 0;
+
+ for (i=audio.first_sound_channel; i<audio.num_channels; i++)
+ {
+#if !defined(PLATFORM_MSDOS)
+ int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
+#else
+ int actual = playlist[i].playingpos;
+#endif
+
+ if (!IS_LOOP(playlist[i]) && actual > longest)
+ {
+ longest = actual;
+ longest_nr = i;
+ }
+ }
+#if defined(PLATFORM_MSDOS)
+ voice_set_volume(playlist[longest_nr].voice, 0);
+ deallocate_voice(playlist[longest_nr].voice);
+#endif
+ PlaylistRemoveSound(longest_nr);
+ }
+
+ /* check if sound is already being played (and how often) */
+ for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
+ if (playlist[i].nr == snd_ctrl.nr)
+ k++;
+
+ /* restart loop sounds only if they are just fading out */
+ if (k >= 1 && IS_LOOP(snd_ctrl))
+ {
+ for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+ {
+ if (playlist[i].nr == snd_ctrl.nr && IS_FADING(playlist[i]))
+ {
+ playlist[i].state &= ~SND_CTRL_FADE;
+ playlist[i].volume = PSND_MAX_VOLUME;
+#if defined(PLATFORM_MSDOS)
+ playlist[i].state |= SND_CTRL_LOOP;
+ voice_stop_volumeramp(playlist[i].voice);
+ voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
+#endif
+ }
+ }
+
+ return;
+ }
+
+ /* don't play sound more than n times simultaneously (with n == 2 for now) */
+ if (k >= 2)
+ {
+ int longest = 0, longest_nr = 0;
+
+ /* look for oldest equal sound */
+ for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+ {
+ int actual;
+
+ if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
+ continue;
+
+#if !defined(PLATFORM_MSDOS)
+ actual = 100 * playlist[i].playingpos / playlist[i].data_len;
+#else
+ actual = playlist[i].playingpos;
+#endif
+ if (actual >= longest)
+ {
+ longest = actual;
+ longest_nr = i;
+ }
+ }
+
+#if defined(PLATFORM_MSDOS)
+ voice_set_volume(playlist[longest_nr].voice, 0);
+ deallocate_voice(playlist[longest_nr].voice);
+#endif
+ PlaylistRemoveSound(longest_nr);
+ }
+
+ /* add new sound to playlist */
+ for(i=0; i<audio.num_channels; i++)
+ {
+#if 0
+ printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
+#endif
+
+ /*
+ if (!playlist[i].active ||
+ (IS_MUSIC(snd_ctrl) && i == audio.music_channel))
+ */
+ if ((i == audio.music_channel && IS_MUSIC(snd_ctrl)) ||
+ (i != audio.music_channel && !playlist[i].active))
+ {
+ snd_ctrl.data_ptr = snd_info->data_ptr;
+ snd_ctrl.data_len = snd_info->data_len;
+ snd_ctrl.format = snd_info->format;
+
+#if 1
+ if (snd_info->data_len == 0)
+ {
+ printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
+ }
+#endif
+
+#if 1
+ if (IS_MUSIC(snd_ctrl) && i == audio.music_channel && playlist[i].active)
+ {
+ printf("THIS SHOULD NEVER HAPPEN! [adding music twice]\n");
+
+#if 1
+ PlaylistRemoveSound(i);
+#endif
+ }
+#endif
+
+ playlist[i] = snd_ctrl;
+ playing_sounds++;
+
+#if 0
+ printf("NEW SOUND %d ADDED TO PLAYLIST\n", snd_ctrl.nr);
+#endif
+
+#if defined(PLATFORM_MSDOS)
+ playlist[i].voice = allocate_voice((SAMPLE *)playlist[i].data_ptr);
+
+ if (snd_ctrl.loop)
+ voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
+
+ voice_set_volume(playlist[i].voice, snd_ctrl.volume);
+ voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
+ voice_start(playlist[i].voice);
+#endif
+ break;
+ }
+ }
+}