aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sfx
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/sfx')
-rw-r--r--engines/sci/sfx/core.cpp6
-rw-r--r--engines/sci/sfx/iterator.cpp4
-rw-r--r--engines/sci/sfx/mixer.h2
-rw-r--r--engines/sci/sfx/pcm-iterator.cpp2
-rw-r--r--engines/sci/sfx/pcm_device.cpp4
-rw-r--r--engines/sci/sfx/player/players.cpp2
-rw-r--r--engines/sci/sfx/player/polled.cpp2
-rw-r--r--engines/sci/sfx/player/realtime.cpp2
-rw-r--r--engines/sci/sfx/sequencer.h2
-rw-r--r--engines/sci/sfx/sfx_core.h40
-rw-r--r--engines/sci/sfx/sfx_engine.h166
-rw-r--r--engines/sci/sfx/sfx_iterator.h350
-rw-r--r--engines/sci/sfx/sfx_iterator_internal.h236
-rw-r--r--engines/sci/sfx/sfx_pcm.h184
-rw-r--r--engines/sci/sfx/sfx_player.h154
-rw-r--r--engines/sci/sfx/sfx_songlib.h191
-rw-r--r--engines/sci/sfx/sfx_time.h85
-rw-r--r--engines/sci/sfx/sfx_timer.h56
-rw-r--r--engines/sci/sfx/softseq.h4
-rw-r--r--engines/sci/sfx/softseq/opl2.cpp2
-rw-r--r--engines/sci/sfx/songlib.cpp2
-rw-r--r--engines/sci/sfx/time.cpp2
-rw-r--r--engines/sci/sfx/timer.cpp2
23 files changed, 1481 insertions, 19 deletions
diff --git a/engines/sci/sfx/core.cpp b/engines/sci/sfx/core.cpp
index 5ff66716b3..4d40d002ca 100644
--- a/engines/sci/sfx/core.cpp
+++ b/engines/sci/sfx/core.cpp
@@ -26,9 +26,9 @@
/* Sound subsystem core: Event handler, sound player dispatching */
#include <stdio.h>
-#include "sci/include/sfx_timer.h"
-#include "sci/include/sfx_iterator_internal.h"
-#include "sci/include/sfx_player.h"
+#include "sci/sfx/sfx_timer.h"
+#include "sci/sfx/sfx_iterator_internal.h"
+#include "sci/sfx/sfx_player.h"
#include "sci/sfx/mixer.h"
#include "sci/include/sci_midi.h"
#include "common/mutex.h"
diff --git a/engines/sci/sfx/iterator.cpp b/engines/sci/sfx/iterator.cpp
index 7c98e6d691..ff4faafde2 100644
--- a/engines/sci/sfx/iterator.cpp
+++ b/engines/sci/sfx/iterator.cpp
@@ -27,8 +27,8 @@
#include <stdio.h>
#include "common/util.h"
-#include "sci/include/sfx_iterator_internal.h"
-#include "sci/include/sfx_player.h"
+#include "sci/sfx/sfx_iterator_internal.h"
+#include "sci/sfx/sfx_player.h"
#include "sci/tools.h"
#include "sci/include/sci_memory.h"
diff --git a/engines/sci/sfx/mixer.h b/engines/sci/sfx/mixer.h
index 286dbc3a89..aea58ce2c9 100644
--- a/engines/sci/sfx/mixer.h
+++ b/engines/sci/sfx/mixer.h
@@ -26,7 +26,7 @@
#ifndef SCI_SFX_MIXER_H
#define SCI_SFX_MIXER_H
-#include "sci/include/sfx_pcm.h"
+#include "sci/sfx/sfx_pcm.h"
namespace Sci {
diff --git a/engines/sci/sfx/pcm-iterator.cpp b/engines/sci/sfx/pcm-iterator.cpp
index 9c72edfa13..7bf9ed6a06 100644
--- a/engines/sci/sfx/pcm-iterator.cpp
+++ b/engines/sci/sfx/pcm-iterator.cpp
@@ -23,7 +23,7 @@
*
*/
-#include "sci/include/sfx_iterator.h"
+#include "sci/sfx/sfx_iterator.h"
#include "sci/tools.h" /* for BREAKPOINT */
#include "sci/include/sci_memory.h"
diff --git a/engines/sci/sfx/pcm_device.cpp b/engines/sci/sfx/pcm_device.cpp
index 267dfa25e2..a0f590ee82 100644
--- a/engines/sci/sfx/pcm_device.cpp
+++ b/engines/sci/sfx/pcm_device.cpp
@@ -23,8 +23,8 @@
*
*/
-#include "sci/include/sfx_time.h"
-#include "sci/include/sfx_pcm.h"
+#include "sci/sfx/sfx_time.h"
+#include "sci/sfx/sfx_pcm.h"
#include "engines/engine.h"
#include "sound/audiostream.h"
#include "sound/mixer.h"
diff --git a/engines/sci/sfx/player/players.cpp b/engines/sci/sfx/player/players.cpp
index 32623d0fc7..131c467cff 100644
--- a/engines/sci/sfx/player/players.cpp
+++ b/engines/sci/sfx/player/players.cpp
@@ -23,7 +23,7 @@
*
*/
-#include "sci/include/sfx_player.h"
+#include "sci/sfx/sfx_player.h"
namespace Sci {
diff --git a/engines/sci/sfx/player/polled.cpp b/engines/sci/sfx/player/polled.cpp
index ab75c705e3..869f7c00b2 100644
--- a/engines/sci/sfx/player/polled.cpp
+++ b/engines/sci/sfx/player/polled.cpp
@@ -27,7 +27,7 @@
#include "common/util.h"
#include "common/file.h"
-#include "sci/include/sfx_player.h"
+#include "sci/sfx/sfx_player.h"
#include "sci/sfx/softseq.h"
#include "sci/sfx/mixer.h"
diff --git a/engines/sci/sfx/player/realtime.cpp b/engines/sci/sfx/player/realtime.cpp
index e749f49220..ab08d7f44b 100644
--- a/engines/sci/sfx/player/realtime.cpp
+++ b/engines/sci/sfx/player/realtime.cpp
@@ -27,7 +27,7 @@
** prays for some reasonable amount of soft real-time, but it's close
** enough, I guess. */
-#include "sci/include/sfx_player.h"
+#include "sci/sfx/sfx_player.h"
#include "sci/sfx/sequencer.h"
namespace Sci {
diff --git a/engines/sci/sfx/sequencer.h b/engines/sci/sfx/sequencer.h
index d292a8100d..803b731449 100644
--- a/engines/sci/sfx/sequencer.h
+++ b/engines/sci/sfx/sequencer.h
@@ -30,7 +30,7 @@
#include "common/scummsys.h"
#include "sci/tools.h" // For GTimeVal
-#include "sci/include/sfx_core.h"
+#include "sci/sfx/sfx_core.h"
#include "sci/sfx/device.h"
#include "sci/include/scitypes.h"
diff --git a/engines/sci/sfx/sfx_core.h b/engines/sci/sfx/sfx_core.h
new file mode 100644
index 0000000000..7ac02d6cfc
--- /dev/null
+++ b/engines/sci/sfx/sfx_core.h
@@ -0,0 +1,40 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _SFX_CORE_H_
+#define _SFX_CORE_H_
+
+#include "common/scummsys.h"
+
+namespace Sci {
+
+#define SFX_OK 0
+#define SFX_ERROR -1
+
+#define MIDI_CHANNELS 16
+
+} // End of namespace Sci
+
+#endif /* !defined(_SFX_CORE_H_) */
diff --git a/engines/sci/sfx/sfx_engine.h b/engines/sci/sfx/sfx_engine.h
new file mode 100644
index 0000000000..60893e550f
--- /dev/null
+++ b/engines/sci/sfx/sfx_engine.h
@@ -0,0 +1,166 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/* Sound engine */
+#ifndef _SFX_ENGINE_H_
+#define _SFX_ENGINE_H_
+
+#include "sci/sfx/sfx_core.h"
+#include "sci/sfx/sfx_songlib.h"
+#include "sci/sfx/sfx_iterator.h"
+#include "sci/include/sciresource.h"
+
+namespace Sci {
+
+#define SOUND_TICK 1000000 / 60
+/* Approximately 16666 microseconds */
+
+
+#define SFX_STATE_FLAG_MULTIPLAY (1 << 0) /* More than one song playable
+** simultaneously ? */
+#define SFX_STATE_FLAG_NOSOUND (1 << 1) /* Completely disable sound playing */
+
+
+#define SFX_DEBUG_SONGS (1 << 0) /* Debug song changes */
+#define SFX_DEBUG_CUES (1 << 1) /* Debug cues, loops, and
+** song completions */
+
+typedef struct {
+ song_iterator_t *it; /* The song iterator at the heart of things */
+ unsigned int flags; /* SFX_STATE_FLAG_* */
+ songlib_t songlib; /* Song library */
+ song_t *song; /* Active song, or start of active song chain */
+ int suspended; /* Whether we are suspended */
+ unsigned int debug; /* Debug flags */
+
+} sfx_state_t;
+
+/***********/
+/* General */
+/***********/
+
+void sfx_init(sfx_state_t *self, ResourceManager *resmgr, int flags);
+/* Initializes the sound engine
+** Parameters: (ResourceManager *) resmgr: Resource manager for initialization
+** (int) flags: SFX_STATE_FLAG_*
+*/
+
+void sfx_exit(sfx_state_t *self);
+/* Deinitializes the sound subsystem
+*/
+
+void sfx_suspend(sfx_state_t *self, int suspend);
+/* Suspends/unsuspends the sound sybsystem
+** Parameters: (int) suspend: Whether to suspend (non-null) or to unsuspend
+*/
+
+int sfx_poll(sfx_state_t *self, song_handle_t *handle, int *cue);
+/* Polls the sound server for cues etc.
+** Returns : (int) 0 if the cue queue is empty, SI_LOOP, SI_CUE, or SI_FINISHED otherwise
+** (song_handle_t) *handle: The affected handle
+** (int) *cue: The sound cue number (if SI_CUE), or the loop number (if SI_LOOP)
+*/
+
+int sfx_poll_specific(sfx_state_t *self, song_handle_t handle, int *cue);
+/* Polls the sound server for cues etc.
+** Parameters: (song_handle_t) handle: The handle to poll
+** Returns : (int) 0 if the cue queue is empty, SI_LOOP, SI_CUE, or SI_FINISHED otherwise
+** (int) *cue: The sound cue number (if SI_CUE), or the loop number (if SI_LOOP)
+*/
+
+int sfx_get_volume(sfx_state_t *self);
+/* Determines the current global volume settings
+** Returns : (int) The global volume, between 0 (silent) and 127 (max. volume)
+*/
+
+void sfx_set_volume(sfx_state_t *self, int volume);
+/* Determines the current global volume settings
+** Parameters: (int) volume: The new global volume, between 0 and 127 (see above)
+*/
+
+void sfx_all_stop(sfx_state_t *self);
+/* Stops all songs currently playing, purges song library
+*/
+
+
+/*****************/
+/* Song basics */
+/*****************/
+
+int sfx_add_song(sfx_state_t *self, song_iterator_t *it, int priority, song_handle_t handle, int resnum);
+/* Adds a song to the internal sound library
+** Parameters: (song_iterator_t *) it: The iterator describing the song
+** (int) priority: Initial song priority (higher <-> more important)
+** (song_handle_t) handle: The handle to associate with the song
+** Returns : (int) 0 on success, nonzero on error
+*/
+
+
+void sfx_remove_song(sfx_state_t *self, song_handle_t handle);
+/* Deletes a song and its associated song iterator from the song queue
+** Parameters: (song_handle_t) handle: The song to remove
+*/
+
+
+/**********************/
+/* Song modifications */
+/**********************/
+
+
+void sfx_song_set_status(sfx_state_t *self, song_handle_t handle, int status);
+/* Sets the song status, i.e. whether it is playing, suspended, or stopped.
+** Parameters: (song_handle_t) handle: Handle of the song to modify
+** (int) status: The song status the song should assume
+** WAITING and PLAYING are set implicitly and essentially describe the same state
+** as far as this function is concerned.
+*/
+
+void sfx_song_renice(sfx_state_t *self, song_handle_t handle, int priority);
+/* Sets the new song priority
+** Parameters: (song_handle_t) handle: The handle to modify
+** (int) priority: The priority to set
+*/
+
+void sfx_song_set_loops(sfx_state_t *self, song_handle_t handle, int loops);
+/* Sets the number of loops for the specified song
+** Parameters: (song_handle_t) handle: The song handle to reference
+** (int) loops: Number of loops to set
+*/
+
+void sfx_song_set_hold(sfx_state_t *self, song_handle_t handle, int hold);
+/* Sets the number of loops for the specified song
+** Parameters: (song_handle_t) handle: The song handle to reference
+** (int) hold: Number of loops to setn
+*/
+
+void sfx_song_set_fade(sfx_state_t *self, song_handle_t handle, fade_params_t *fade_setup);
+/* Instructs a song to be faded out
+** Parameters: (song_handle_t) handle: The song handle to reference
+** (fade_params_t *) fade_setup: The precise fade-out configuration to use
+*/
+
+} // End of namespace Sci
+
+#endif /* !defined(_SFX_ENGINE_H_) */
diff --git a/engines/sci/sfx/sfx_iterator.h b/engines/sci/sfx/sfx_iterator.h
new file mode 100644
index 0000000000..9dc1f3a3b3
--- /dev/null
+++ b/engines/sci/sfx/sfx_iterator.h
@@ -0,0 +1,350 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/* Song iterator declarations */
+
+#ifndef _SCI_SFX_ITERATOR_H_
+#define _SCI_SFX_ITERATOR_H_
+
+#include "sci/sfx/sfx_pcm.h"
+
+namespace Sci {
+
+#define SI_FINISHED -1 /* Song finished playing */
+#define SI_LOOP -2 /* Song just looped */
+#define SI_ABSOLUTE_CUE -3 /* Found a song cue (absolute) */
+#define SI_RELATIVE_CUE -4 /* Found a song cue (relative) */
+#define SI_PCM -5 /* Found a PCM */
+#define SI_IGNORE -6 /* This event got edited out by the remapper */
+#define SI_MORPH -255 /* Song iterator requested self-morph. */
+
+#define FADE_ACTION_NONE 0
+#define FADE_ACTION_FADE_AND_STOP 1
+#define FADE_ACTION_FADE_AND_CONT 2
+
+typedef struct {
+ int ticks_per_step;
+ int final_volume;
+ int step_size;
+ int action;
+} fade_params_t;
+
+#define SONG_ITERATOR_MESSAGE_ARGUMENTS_NR 2
+
+/* Helper defs for messages */
+/* Base messages */
+#define _SIMSG_BASE 0 /* Any base decoder */
+#define _SIMSG_BASEMSG_SET_LOOPS 0 /* Set loops */
+#define _SIMSG_BASEMSG_CLONE 1 /* Clone object and data. Must provide the
+** (possibly negative) number of ticks that have
+** passed since the last delay time started being
+** used */
+#define _SIMSG_BASEMSG_SET_PLAYMASK 2 /* Set the current playmask for filtering */
+#define _SIMSG_BASEMSG_SET_RHYTHM 3 /* Activate/deactivate rhythm channel */
+#define _SIMSG_BASEMSG_ACK_MORPH 4 /* Acknowledge self-morph */
+#define _SIMSG_BASEMSG_STOP 5 /* Stop iterator */
+#define _SIMSG_BASEMSG_PRINT 6 /* Print self to stderr, after printing param1 tabs */
+#define _SIMSG_BASEMSG_SET_HOLD 7 /* Set value of hold parameter to expect */
+#define _SIMSG_BASEMSG_SET_FADE 8 /* Set fade parameters */
+
+/* "Plastic" (discardable) wrapper messages */
+#define _SIMSG_PLASTICWRAP 1 /* Any base decoder */
+#define _SIMSG_PLASTICWRAP_ACK_MORPH 4 /* Acknowledge self-morph */
+
+/* Messages */
+#define SIMSG_SET_LOOPS(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_LOOPS,(x),0
+#define SIMSG_SET_PLAYMASK(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_PLAYMASK,(x),0
+#define SIMSG_SET_RHYTHM(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_RHYTHM,(x),0
+#define SIMSG_CLONE(x) _SIMSG_BASE,_SIMSG_BASEMSG_CLONE,(x),0
+#define SIMSG_ACK_MORPH _SIMSG_PLASTICWRAP,_SIMSG_PLASTICWRAP_ACK_MORPH,0,0
+#define SIMSG_STOP _SIMSG_BASE,_SIMSG_BASEMSG_STOP,0,0
+#define SIMSG_PRINT(indentation) _SIMSG_BASE,_SIMSG_BASEMSG_PRINT,(indentation),0
+#define SIMSG_SET_HOLD(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_HOLD,(x),0
+/*#define SIMSG_SET_FADE(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_FADE,(x),0*/
+
+/* Message transmission macro: Takes song reference, message reference */
+#define SIMSG_SEND(o, m) songit_handle_message(&(o), songit_make_message((o)->ID, m))
+#define SIMSG_SEND_FADE(o, m) songit_handle_message(&(o), songit_make_ptr_message((o)->ID, _SIMSG_BASE, _SIMSG_BASEMSG_SET_FADE, m, 0))
+
+/* Event listener interface */
+struct listener_t {
+ void (*notify)(void *self, void *notifier);
+ void *self;
+};
+
+typedef unsigned long songit_id_t;
+
+typedef struct {
+ songit_id_t ID;
+ unsigned int recipient; /* Type of iterator supposed to receive this */
+ unsigned int type;
+ union {
+ unsigned int i;
+ void * p;
+ } args[SONG_ITERATOR_MESSAGE_ARGUMENTS_NR];
+} song_iterator_message_t;
+
+#define INHERITS_SONG_ITERATOR \
+ songit_id_t ID; \
+ guint16 channel_mask; \
+ fade_params_t fade; \
+ unsigned int flags; \
+ int priority; \
+ int (*next) (song_iterator_t *self, unsigned char *buf, int *buf_size); \
+ sfx_pcm_feed_t * (*get_pcm_feed) (song_iterator_t *s); \
+ song_iterator_t * (* handle_message)(song_iterator_t *self, song_iterator_message_t msg); \
+ void (*init) (struct _song_iterator *self); \
+ void (*cleanup) (struct _song_iterator *self); \
+ int (*get_timepos) (struct _song_iterator *self); \
+ listener_t death_listeners[SONGIT_MAX_LISTENERS]; \
+ int death_listeners_nr \
+
+#define SONGIT_MAX_LISTENERS 2
+
+typedef struct _song_iterator {
+
+ songit_id_t ID;
+ guint16 channel_mask; /* Bitmask of all channels this iterator will use */
+ fade_params_t fade;
+ unsigned int flags;
+ int priority;
+
+ int (*next)(struct _song_iterator *self,
+ unsigned char *buf, int *result);
+ /* Reads the next MIDI operation _or_ delta time
+ ** Parameters: (song_iterator_t *) self
+ ** (byte *) buf: The buffer to write to (needs to be able to
+ ** store at least 4 bytes)
+ ** Returns : (int) zero if a MIDI operation was written, SI_FINISHED
+ ** if the song has finished playing, SI_LOOP if looping
+ ** (after updating the loop variable), SI_CUE if we found
+ ** a cue, SI_PCM if a PCM was found, or the number of ticks
+ ** to wait before this function should be called next.
+ ** (int) *result: Number of bytes written to the buffer
+ ** (equals the number of bytes that need to be passed
+ ** to the lower layers) for 0, the cue value for SI_CUE,
+ ** or the number of loops remaining for SI_LOOP.
+ ** If SI_PCM is returned, get_pcm() may be used to retrieve the associated
+ ** PCM, but this must be done before any subsequent calls to next().
+ */
+
+ sfx_pcm_feed_t * (*get_pcm_feed)(struct _song_iterator *self);
+ /* Checks for the presence of a pcm sample
+ ** Parameters: (song_iterator_t *) self
+ ** Returns : (sfx_pcm_feed_t *) NULL if no PCM data was found, a
+ ** PCM feed otherwise
+ */
+
+
+ struct _song_iterator *
+ (* handle_message)(struct _song_iterator *self, song_iterator_message_t msg);
+ /* Handles a message to the song iterator
+ ** Parameters: (song_iterator_t *) self
+ ** (song_iterator_messag_t) msg: The message to handle
+ ** Returns : (song_iterator_t *) NULL if the message was not understood,
+ ** self if the message could be handled, or a new song iterator
+ ** if the current iterator had to be morphed (but the message could
+ ** still be handled)
+ ** This function is not supposed to be called directly; use
+ ** songit_handle_message() instead. It should not recurse, since songit_handle_message()
+ ** takes care of that and makes sure that its delegate received the message (and
+ ** was morphed) before self.
+ */
+
+
+ void (*init)(struct _song_iterator *self);
+ /* Resets/initializes the sound iterator
+ ** Parameters: (song_iterator_t *) self
+ ** Returns : (void)
+ */
+
+ void (*cleanup)(struct _song_iterator *self);
+ /* Frees any content of the iterator structure
+ ** Parameters: (song_iterator_t *) self
+ ** Does not physically free(self) yet. May be NULL if nothing needs to be done.
+ ** Must not recurse on its delegate.
+ */
+
+ int (*get_timepos)(struct _song_iterator *self);
+ /* Gets the song position to store in a savegame
+ ** Parameters: (song_iterator_t *) self
+ */
+
+ /* Death listeners */
+ /* These are not reset during initialisation */
+ listener_t death_listeners[SONGIT_MAX_LISTENERS];
+ int death_listeners_nr;
+
+ /* See songit_* for the constructor and non-virtual member functions */
+
+} song_iterator_t;
+
+
+/* Song iterator flags */
+#define SONGIT_FLAG_CLONE (1 << 0) /* This flag is set for clones, which are exclusively used in song players.
+** Thus, this flag distinguishes song iterators in the main thread from those
+** in the song-player thread. */
+
+void song_iterator_add_death_listener(song_iterator_t *it,
+ void *client,
+ void (*notify)(void *self, void *notifier));
+/* Adds a death listener to a song iterator
+** Parameters: (song_iterator_t *) it: The iterator to add to
+** (void *) client: The object wanting to be notified
+** (void* x void* -> void) notify: The notification function
+** to invoke
+** Effects: Fatally terminates the program if no listener slots are
+** available
+** Death listeners are NOT cloned.
+*/
+
+void song_iterator_remove_death_listener(song_iterator_t *it,
+ void *client);
+/* Removes a death listener from a song iterator
+** Parameters: (song_iterator_t *) it: The iterator to modify
+** (void *) client: The object no longer wanting to be notified
+** Effects: Fatally terminates the program if the listener was not
+** found
+** Death listeners are NOT cloned.
+*/
+
+/********************************/
+/*-- Song iterator operations --*/
+/********************************/
+
+#define SCI_SONG_ITERATOR_TYPE_SCI0 0
+#define SCI_SONG_ITERATOR_TYPE_SCI1 1
+
+#define IT_READER_MASK_MIDI (1 << 0)
+#define IT_READER_MASK_DELAY (1 << 1)
+#define IT_READER_MASK_LOOP (1 << 2)
+#define IT_READER_MASK_CUE (1 << 3)
+#define IT_READER_MASK_PCM (1 << 4)
+#define IT_READER_MAY_FREE (1 << 10) /* Free SI_FINISHED iterators */
+#define IT_READER_MAY_CLEAN (1 << 11)
+/* MAY_CLEAN: May instantiate cleanup iterators
+** (use for players; this closes open channels at the end of a song) */
+
+#define IT_READER_MASK_ALL ( IT_READER_MASK_MIDI \
+ | IT_READER_MASK_DELAY \
+ | IT_READER_MASK_LOOP \
+ | IT_READER_MASK_CUE \
+ | IT_READER_MASK_PCM )
+
+int songit_next(song_iterator_t **it, unsigned char *buf, int *result, int mask);
+/* Convenience wrapper around it->next
+** Parameters: (song_iterator_t **it) Reference to the iterator to access
+** (byte *) buf: The buffer to write to (needs to be able to
+** store at least 4 bytes)
+** (int) mask: IT_READER_MASK options specifying the events to
+** listen for
+** Returns : (int) zero if a MIDI operation was written, SI_FINISHED
+** if the song has finished playing, SI_LOOP if looping
+** (after updating the loop variable), SI_CUE if we found
+** a cue, SI_PCM if a PCM was found, or the number of ticks
+** to wait before this function should be called next.
+** (int) *result: Number of bytes written to the buffer
+** (equals the number of bytes that need to be passed
+** to the lower layers) for 0, the cue value for SI_CUE,
+** or the number of loops remaining for SI_LOOP.
+*/
+
+song_iterator_t *songit_new(unsigned char *data, unsigned int size, int type, songit_id_t id);
+/* Constructs a new song iterator object
+** Parameters: (byte *) data: The song data to iterate over
+** (unsigned int) size: Number of bytes in the song
+** (int) type: One of the SCI_SONG_ITERATOR_TYPEs
+** (songit_id_t) id: An ID for addressing the song iterator
+** Returns : (song_iterator_t *) A newly allocated but uninitialized song
+** iterator, or NULL if 'type' was invalid or unsupported
+*/
+
+song_iterator_t *songit_new_tee(song_iterator_t *left, song_iterator_t *right, int may_destroy);
+/* Combines two iterators, returns the next event available from either
+** Parameters: (song_iterator_t *) left: One of the iterators
+** (song_iterator_t *) right: The other iterator
+** (int) may_destroy: Whether completed song iterators may be
+** destroyed
+** Returns : (song_iterator_t *) A combined iterator, as suggested above
+*/
+
+
+void songit_free(song_iterator_t *it);
+/* Frees a song iterator and the song it wraps
+** Parameters: (song_iterator_t *) it: The song iterator to free
+** Returns : (void)
+*/
+
+song_iterator_message_t songit_make_message(songit_id_t id,
+ int recipient_class, int type, int a1, int a2);
+/* Create a song iterator message
+** Parameters: (songit_id_t) id: song ID the message is targetted to
+** (int) recipient_class: Message recipient class
+** (int) type: Message type
+** (int x int) a1, a2: Arguments
+** You should only use this with the SIMSG_* macros
+*/
+
+song_iterator_message_t songit_make_ptr_message(songit_id_t id,
+ int recipient_class, int type, void * a1, int a2);
+/* Create a song iterator message, wherein the first parameter is a pointer
+** Parameters: (songit_id_t) id: song ID the message is targetted to
+** (int) recipient_class: Message recipient class
+** (int) type: Message type
+** (void* x int) a1, a2: Arguments
+** You should only use this with the SIMSG_* macros
+*/
+
+int songit_handle_message(song_iterator_t **it_reg, song_iterator_message_t msg);
+/* Handles a message to the song iterator
+** Parameters: (song_iterator_t **): A reference to the variable storing the song iterator
+** Returns : (int) Non-zero if the message was understood
+** The song iterator may polymorph as result of msg, so a writeable reference is required.
+*/
+
+
+song_iterator_t *songit_clone(song_iterator_t *it, int delta);
+/* Clones a song iterator
+** Parameters: (song_iterator_t *) it: The iterator to clone
+** (int) delta: Number of ticks that still need to elapse until
+** the next item should be read from the song iterator
+** Returns : (song_iterator_t *) A shallow clone of 'it'.
+** This performs a clone on the bottom-most part (containing the actual song data) _only_.
+** The justification for requiring 'delta' to be passed in here is that this
+** is typically maintained outside of the song iterator.
+*/
+
+
+int sfx_play_iterator_pcm(song_iterator_t *it, unsigned long handle);
+/* Plays a song iterator that found a PCM through a PCM device, if possible
+** Parameters: (song_iterator_t *) it: The iterator to play
+** (song_handle_t) handle: Debug handle
+** Returns : (int) 0 if the effect will not be played, nonzero if it will
+** This assumes that the last call to 'it->next()' returned SI_PCM.
+*/
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/sfx/sfx_iterator_internal.h b/engines/sci/sfx/sfx_iterator_internal.h
new file mode 100644
index 0000000000..4c104b5c52
--- /dev/null
+++ b/engines/sci/sfx/sfx_iterator_internal.h
@@ -0,0 +1,236 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _SFX_ITERATOR_INTERNAL_
+#define _SFX_ITERATOR_INTERNAL_
+
+#include "sci/sfx/sfx_iterator.h"
+#include "sci/include/sci_midi.h"
+
+namespace Sci {
+
+/* States */
+
+#define SI_STATE_UNINITIALISED -1
+#define SI_STATE_DELTA_TIME 0 /* Now at a delta time */
+#define SI_STATE_COMMAND 1 /* Now at a MIDI operation */
+#define SI_STATE_PENDING 2 /* Pending for loop */
+#define SI_STATE_FINISHED 3 /* End of song */
+#define SI_STATE_PCM 4 /* Should report a PCM next (-> DELTA_TIME) */
+#define SI_STATE_PCM_MAGIC_DELTA 5 /* Should report a ``magic'' one tick delta time next (goes on to FINISHED) */
+
+
+/* Iterator types */
+
+#define SCI_SONG_ITERATOR_TYPE_SCI0 0
+#define SCI_SONG_ITERATOR_TYPE_SCI1 1
+
+#define SIPFX __FILE__" : "
+
+
+typedef struct {
+ int state; /* SI_STATE_* */
+ int offset; /* Offset into the data chunk */
+ int end; /* Last allowed byte in track */
+ int id; /* Some channel ID */
+ int loop_offset;
+ int delay; /* Number of ticks before the
+ ** specified channel is next
+ ** used, or
+ ** CHANNEL_DELAY_MISSING to
+ ** indicate that the delay has
+ ** not yet been read */
+
+ /* Two additional offsets for recovering: */
+ int initial_offset;
+ int playmask; /* Active playmask (MIDI channels to play in here) */
+ int notes_played; /* #of notes played since the last loop start */
+ int loop_timepos; /* Total delay for this channel's loop marker */
+ int total_timepos; /* Number of ticks since the beginning, ignoring loops */
+ int timepos_increment; /* Number of ticks until the next command (to add) */
+
+ int saw_notes; /* Bitmask of channels we have currently played notes on */
+ byte last_cmd; /* Last operation executed, for running status */
+} song_iterator_channel_t;
+
+#define INHERITS_BASE_SONG_ITERATOR \
+ INHERITS_SONG_ITERATOR; /* aka "extends song iterator" */ \
+ \
+ int polyphony[MIDI_CHANNELS]; /* # of simultaneous notes on each */ \
+ int importance[MIDI_CHANNELS]; /* priority rating for each channel, 0 means unrated. */ \
+ \
+ \
+ int ccc; /* Cumulative cue counter, for those who need it */ \
+ unsigned char resetflag; /* for 0x4C -- on DoSound StopSound, do we return to start? */ \
+ int device_id; /* ID of the device we generating events for */ \
+ int active_channels; /* Number of active channels */ \
+ unsigned int size; /* Song size */ \
+ unsigned char *data; \
+ \
+ int loops; /* Number of loops remaining */ \
+ int recover_delay
+
+typedef struct _base_song_iterator {
+ INHERITS_BASE_SONG_ITERATOR;
+} base_song_iterator_t;
+
+/********************************/
+/*--------- SCI 0 --------------*/
+/********************************/
+
+typedef struct {
+ INHERITS_BASE_SONG_ITERATOR;
+ song_iterator_channel_t channel;
+ int delay_remaining; /* Number of ticks that haven't been polled yet */
+} sci0_song_iterator_t;
+
+
+/********************************/
+/*--------- SCI 1 --------------*/
+/********************************/
+
+
+typedef struct _sci1_sample {
+ int delta; /* Time left-- initially, this is 'Sample point 1'.
+ ** After initialisation, it is 'sample point 1 minus the sample point of the previous sample' */
+ int size;
+ int announced; /* Announced for download (SI_PCM) */
+ sfx_pcm_config_t format;
+ byte *data;
+ struct _sci1_sample *next;
+} sci1_sample_t;
+
+typedef struct {
+ INHERITS_BASE_SONG_ITERATOR;
+ song_iterator_channel_t channels[MIDI_CHANNELS];
+
+ /* Invariant: Whenever channels[i].delay == CHANNEL_DELAY_MISSING,
+ ** channel_offset[i] points to a delta time object. */
+
+ int initialised; /* Whether the MIDI channel setup has been initialised */
+ int channels_nr; /* Number of channels actually used */
+ sci1_sample_t *next_sample;
+ int channels_looped; /* Number of channels that are ready to loop */
+
+ int delay_remaining; /* Number of ticks that haven't been polled yet */
+ int hold;
+ \
+} sci1_song_iterator_t;
+
+#define PLAYMASK_NONE 0x0
+
+/*********************************/
+/*---------- Cleanup ------------*/
+/*********************************/
+
+
+song_iterator_t *new_cleanup_iterator(unsigned int channels);
+/* Creates a new song iterator with the purpose of sending notes-off channel commands
+** Parameters: (unsigned int) channels: Channel mask to send these commands for
+** Returns : A song iterator with the aforementioned purpose
+*/
+
+int is_cleanup_iterator(song_iterator_t *it);
+/* Determines whether a given song iterator is a cleanup song iterator
+** Parameters: (song_iterator_t *) it: The iterator to check
+** Returns : (int) 1 iff 'it' is a cleanup song iterator
+** No deep recursion/delegation is considered.
+*/
+
+
+/**********************************/
+/*--------- Fast Forward ---------*/
+/**********************************/
+
+typedef struct {
+ INHERITS_SONG_ITERATOR;
+ song_iterator_t *delegate;
+ int delta; /* Remaining time */
+} fast_forward_song_iterator_t;
+
+
+song_iterator_t *new_fast_forward_iterator(song_iterator_t *it, int delta);
+/* Creates a new song iterator which fast-forwards
+** Parameters: (song_iterator_t *) it: The iterator to wrap
+** (int) delta: The number of ticks to skip
+** Returns : (song_iterator_t) A newly created song iterator
+** which skips all delta times
+** until 'delta' has been used up
+*/
+
+/**********************************/
+/*--------- Fast Forward ---------*/
+/**********************************/
+
+#define MAX_BUF_SIZE 4
+
+#define TEE_LEFT 0
+#define TEE_RIGHT 1
+#define TEE_LEFT_ACTIVE (1<<0)
+#define TEE_RIGHT_ACTIVE (1<<1)
+#define TEE_LEFT_READY (1<<2) /* left result is ready */
+#define TEE_RIGHT_READY (1<<3) /* right result is ready */
+#define TEE_LEFT_PCM (1<<4)
+#define TEE_RIGHT_PCM (1<<5)
+
+#define TEE_MORPH_NONE 0 /* Not waiting to self-morph */
+#define TEE_MORPH_READY 1 /* Ready to self-morph */
+
+typedef struct {
+ INHERITS_SONG_ITERATOR;
+
+ int status;
+
+ int may_destroy; /* May destroy song iterators */
+
+ int morph_deferred; /* One of TEE_MORPH_* above */
+
+ struct {
+ song_iterator_t *it;
+ byte buf[MAX_BUF_SIZE];
+ int result;
+ int retval;
+
+ byte channel_remap[MIDI_CHANNELS];
+ /* Remapping for channels */
+
+ } children[2];
+} tee_song_iterator_t;
+
+
+sfx_pcm_feed_t *sfx_iterator_make_feed(byte *base_data, int offset,
+ int size,
+ sfx_pcm_config_t conf);
+/* Generates a feed for a song iterator
+** Parameters: (byte *) base_data: A refcounted memory chunk containing
+** (among other things) PCM data
+** (int) offset; Offset into base_data
+** (int) size: Number of bytes to consider
+** (pcm_data_internal_t) conf: PCM encoding
+*/
+
+} // End of namespace Sci
+
+#endif /* !defined(_SFX_ITERATOR_INTERNAL_ */
diff --git a/engines/sci/sfx/sfx_pcm.h b/engines/sci/sfx/sfx_pcm.h
new file mode 100644
index 0000000000..abb1704741
--- /dev/null
+++ b/engines/sci/sfx/sfx_pcm.h
@@ -0,0 +1,184 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _SFX_PCM_H_
+#define _SFX_PCM_H_
+
+#include "sci/sfx/sfx_core.h"
+#include "sci/sfx/sfx_timer.h"
+#include "sci/sfx/sfx_time.h"
+#include "sci/include/scitypes.h"
+
+namespace Sci {
+
+#define SFX_PCM_MONO 0
+#define SFX_PCM_STEREO_LR 1 /* left sample, then right sample */
+#define SFX_PCM_STEREO_RL 2 /* right sample, then left sample */
+
+/* The following are used internally by the mixer */
+#define SFX_PCM_FORMAT_LMASK 0x7
+#define SFX_PCM_FORMAT_BE 0
+#define SFX_PCM_FORMAT_LE 1
+#define SFX_PCM_FORMAT_ENDIANNESS 1
+#define SFX_PCM_FORMAT_8 0
+#define SFX_PCM_FORMAT_16 2
+
+
+/* Pick one of these formats (including the _NATIVE) ones for your PCM feed */
+#define SFX_PCM_FORMAT_U8 (0x0080 | SFX_PCM_FORMAT_8) /* Unsigned (bias 128) 8 bit format */
+#define SFX_PCM_FORMAT_S8 (0x0000 | SFX_PCM_FORMAT_8) /* Signed 8 bit format */
+#define SFX_PCM_FORMAT_U16_LE (0x8000 | SFX_PCM_FORMAT_16 | SFX_PCM_FORMAT_LE) /* Unsigned (bias 32768) 16 bit LE format */
+#define SFX_PCM_FORMAT_S16_LE (0x0000 | SFX_PCM_FORMAT_16 | SFX_PCM_FORMAT_LE) /* Signed 16 bit format, little endian */
+#define SFX_PCM_FORMAT_U16_BE (0x8000 | SFX_PCM_FORMAT_16 | SFX_PCM_FORMAT_BE) /* Unsigned (bias 32768) 16 bit BE format */
+#define SFX_PCM_FORMAT_S16_BE (0x0000 | SFX_PCM_FORMAT_16 | SFX_PCM_FORMAT_BE) /* Signed 16 bit format, big endian */
+
+#ifdef SCUMM_BIG_ENDIAN
+# define SFX_PCM_FORMAT_U16_NATIVE SFX_PCM_FORMAT_U16_BE
+# define SFX_PCM_FORMAT_S16_NATIVE SFX_PCM_FORMAT_S16_BE
+#else
+# define SFX_PCM_FORMAT_U16_NATIVE SFX_PCM_FORMAT_U16_LE
+# define SFX_PCM_FORMAT_S16_NATIVE SFX_PCM_FORMAT_S16_LE
+#endif
+
+#define SFX_PCM_FRAME_SIZE(conf) ((conf).stereo? 2 : 1) * (((conf).format & SFX_PCM_FORMAT_16)? 2 : 1)
+
+
+typedef struct {
+ int rate; /* Sampling rate */
+ int stereo; /* The stereo mode used (SFX_PCM_MONO or SFX_PCM_STEREO_*) */
+ unsigned int format; /* Sample format (SFX_PCM_FORMAT_*) */
+} sfx_pcm_config_t;
+
+typedef struct _sfx_pcm_device {
+ /* SFX devices are PCM players, i.e. output drivers for digitalised audio (sequences of audio samples).
+ ** Implementors are (in general) allowed to export specifics of these devices and let the mixer handle
+ ** endianness/signedness/bit size/mono-vs-stereo conversions.
+ */
+
+ int (*init)(struct _sfx_pcm_device *self);
+ /* Initializes the device
+ ** Parameters: (sfx_pcm_device_t *) self: Self reference
+ ** Returns : (int) SFX_OK on success, SFX_ERROR if the device could not be
+ ** opened
+ ** This should attempt to open the highest quality output allowed by any options
+ ** specified beforehand.
+ */
+
+ int (*output)(struct _sfx_pcm_device *self, byte *buf,
+ int count, sfx_timestamp_t *timestamp);
+ /* Writes output to the device
+ ** Parameters: (sfx_pcm_device_t *) self: Self reference
+ ** (byte *) buf: The buffer to write
+ ** (int) count: Number of /frames/ that should be written
+ ** (sfx_timestamp_t *) timestamp: Optional point in time
+ ** for which the PCM data is scheduled
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on error
+ ** The size of the buffer allocated as 'buf' equals buf_size.
+ ** 'buf' is guaranteed not to be modified in between calls to 'output()'.
+ ** 'timestamp' is guaranteed to be used only in sequential order, but not
+ ** guaranteed to be used in all cases. It is guaranteed to be compaible with
+ ** the sample rate used by the device itself (i.e., the sfx_time.h functionality
+ ** is applicable)
+ */
+
+ sfx_timestamp_t
+ (*get_output_timestamp)(struct _sfx_pcm_device *self);
+ /* Determines the timestamp for 'output'
+ ** Parameters: (sfx_pcm_device_t *) self: Self reference
+ ** Returns : (sfx_timestamp_t) A timestamp (with the device's conf.rate)
+ ** describing the point in time at which
+ ** the next frame passed to 'output'
+ ** will be played
+ ** This function is OPTIONAL and may be NULL, but it is recommended
+ ** that pcm device implementers attempt to really implement it.
+ */
+
+ /* The following must be set after initialisation */
+ sfx_pcm_config_t conf;
+ int buf_size; /* Output buffer size, i.e. the number of frames (!)
+ ** that can be queued by this driver before calling
+ ** output() will block or fail, drained according
+ ** to conf.rate */
+
+} sfx_pcm_device_t;
+
+
+#define PCM_FEED_TIMESTAMP 0 /* New timestamp available */
+#define PCM_FEED_IDLE 1 /* No sound ATM, but new timestamp may be available later */
+#define PCM_FEED_EMPTY 2 /* Feed is finished, can be destroyed */
+
+typedef struct _sfx_pcm_feed_t {
+ /* PCM feeds are sources of input for the PCM mixer. Their member functions
+ ** are invoked as callbacks on demand, to provide the mixer with input it
+ ** (in turn) passes on to PCM output devices.
+ ** PCM feeds must explicitly register themselves with the mixer in order
+ ** to be considered.
+ */
+
+ int (*poll)(struct _sfx_pcm_feed_t *self, byte *dest, int size);
+ /* Asks the PCM feed to write out the next stuff it would like to have written
+ ** Parameters: (sfx_pcm_feed_t *) self: Self reference
+ ** (byte *) dest: The destination buffer to write to
+ ** (int) size: The maximum number of _frames_ (not neccessarily bytes)
+ ** to write
+ ** Returns : (int) The number of frames written
+ ** If the number of frames written is smaller than 'size', the PCM feed will
+ ** be queried for a new timestamp afterwards, or destroyed if no new timestamp
+ ** is available.
+ */
+
+ void (*destroy)(struct _sfx_pcm_feed_t *self);
+ /* Asks the PCM feed to free all resources it occupies
+ ** Parameters: (sfx_pcm_feed_t *) self: Self reference
+ ** free(self) should be part of this function, if applicable.
+ */
+
+ int
+ (*get_timestamp)(struct _sfx_pcm_feed_t *self, sfx_timestamp_t *timestamp);
+ /* Determines the timestamp of the next frame-to-read
+ ** Returns : (sfx_timestamp_t) timestamp: The timestamp of the next frame
+ ** (int) PCM_FEED_*
+ ** This function is OPTIONAL and may be NULL
+ */
+
+ void *internal; /* The private bits of a PCM feed. */
+
+ sfx_pcm_config_t conf; /* The channel's setup */
+
+ const char *debug_name; /* The channel name, for debugging */
+ int debug_nr; /* A channel number relative to the channel name, for debugging
+ ** (print in hex) */
+ int frame_size; /* Frame size, computed by the mixer for the feed */
+
+} sfx_pcm_feed_t;
+
+int sfx_pcm_available();
+/* Determines whether a PCM device is available and has been initialised
+** Returns : (int) zero iff no PCM device is available
+*/
+
+} // End of namespace Sci
+
+#endif /* !defined(_SFX_PCM_H_) */
diff --git a/engines/sci/sfx/sfx_player.h b/engines/sci/sfx/sfx_player.h
new file mode 100644
index 0000000000..b1e6695f14
--- /dev/null
+++ b/engines/sci/sfx/sfx_player.h
@@ -0,0 +1,154 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/* song player structure */
+
+#ifndef _SFX_PLAYER_H
+#define _SFX_PLAYER_H
+
+#include "sci/sfx/sfx_engine.h"
+#include "sci/sfx/sfx_iterator.h"
+#include "sci/include/sciresource.h"
+
+namespace Sci {
+
+typedef void tell_synth_func(int buf_nr, byte *buf);
+
+typedef struct {
+ const char *name;
+ const char *version;
+
+ int (*set_option)(char *name, char *value);
+ /* Sets an option for player timing mechanism
+ ** Parameters: (char *) name: The name describing what to set
+ ** (char *) value: The value to set
+ ** Returns : (int) SFX_OK, or SFX_ERROR if the name wasn't understood
+ */
+
+ int (*init)(ResourceManager *resmgr, int expected_latency);
+ /* Initializes the player
+ ** Parameters: (ResourceManager *) resmgr: A resource manager for driver initialization
+ ** (int) expected_latency: Expected delay in between calls to 'maintenance'
+ ** (in microseconds)
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int (*add_iterator)(song_iterator_t *it, GTimeVal start_time);
+ /* Adds an iterator to the song player
+ ** Parameters: (songx_iterator_t *) it: The iterator to play
+ ** (GTimeVal) start_time: The time to assume as the
+ ** time the first MIDI command executes at
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** The iterator should not be cloned (to avoid memory leaks) and
+ ** may be modified according to the needs of the player.
+ ** Implementors may use the 'sfx_iterator_combine()' function
+ ** to add iterators onto their already existing iterators
+ */
+
+ int (*fade_out)();
+ /* Fades out the currently playing song (within two seconds
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int (*stop)();
+ /* Stops the currently playing song and deletes the associated iterator
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int (*iterator_message)(song_iterator_message_t msg);
+ /* Transmits a song iterator message to the active song
+ ** Parameters: (song_iterator_message_t) msg: The message to transmit
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** OPTIONAL -- may be NULL
+ ** If this method is not present, sending messages will stop
+ ** and re-start playing, so it is preferred that it is present
+ */
+
+ int (*pause)(); /* OPTIONAL -- may be NULL */
+ /* Pauses song playing
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int (*resume)(); /* OPTIONAL -- may be NULL */
+ /* Resumes song playing after a pause
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int (*exit)();
+ /* Stops the player
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ void (*maintenance)(); /* OPTIONAL -- may be NULL */
+ /* Regularly called maintenance function
+ ** This function is called frequently and regularly (if present), it can be
+ ** used to emit sound.
+ */
+
+ tell_synth_func *tell_synth;
+ /* Pass a raw MIDI event to the synth
+ Parameters: (int) argc: Length of buffer holding the midi event
+ (byte *) argv: The buffer itself
+ */
+
+ int polyphony; /* Number of voices that can play simultaneously */
+
+} sfx_player_t;
+
+sfx_player_t *sfx_find_player(char *name);
+/* Looks up a player by name or finds the default player
+** Parameters: (char *) name: Name of the player to look up, or NULL for dedault
+** Returns : (sfx_player_t *) The player requested, or NULL if none was found
+*/
+
+tell_synth_func *sfx_get_player_tell_func();
+/* Gets the callback function of the player in use.
+** Returns: (tell_synth_func *) The callback function.
+*/
+
+int sfx_get_player_polyphony();
+/* Determines the polyphony of the player in use
+** Returns : (int) Number of voices the active player can emit
+*/
+
+void sfx_reset_player();
+/* Tells the player to stop its internal iterator
+** Parameters: None.
+** Returns: Nothing.
+ */
+
+song_iterator_t *sfx_iterator_combine(song_iterator_t *it1, song_iterator_t *it2);
+/* Combines two song iterators into one
+** Parameters: (sfx_iterator_t *) it1: One of the two iterators, or NULL
+** (sfx_iterator_t *) it2: The other iterator, or NULL
+** Returns : (sfx_iterator_t *) A combined iterator
+** If a combined iterator is returned, it will be flagged to be allowed to
+** dispose of 'it1' and 'it2', where applicable. This means that this
+** call should be used by song players, but not by the core sound system
+*/
+
+} // End of namespace Sci
+
+#endif /* !_SFX_PLAYER_H */
diff --git a/engines/sci/sfx/sfx_songlib.h b/engines/sci/sfx/sfx_songlib.h
new file mode 100644
index 0000000000..6b968bbe08
--- /dev/null
+++ b/engines/sci/sfx/sfx_songlib.h
@@ -0,0 +1,191 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/* Song library */
+
+#ifndef _SCI_SFX_SONGLIB_H_
+#define _SCI_SFX_SONGLIB_H_
+
+#include "common/scummsys.h"
+
+#include "sci/tools.h" // For GTimeVal
+#include "sci/include/scitypes.h"
+#include "sci/sfx/sfx_iterator.h"
+
+namespace Sci {
+
+#define SOUND_STATUS_STOPPED 0
+#define SOUND_STATUS_PLAYING 1
+#define SOUND_STATUS_SUSPENDED 2
+/* suspended: only if ordered from kernel space */
+#define SOUND_STATUS_WAITING 3
+/* "waiting" means "tagged for playing, but not active right now" */
+
+typedef unsigned long song_handle_t;
+
+typedef enum {
+ RESTORE_BEHAVIOR_CONTINUE, /* restart a song when restored from
+ a saved game */
+ RESTORE_BEHAVIOR_RESTART /* continue it from where it was */
+} RESTORE_BEHAVIOR;
+
+typedef struct _song {
+ song_handle_t handle;
+ int resource_num; /* Resource number */
+ int priority; /* Song priority (more important if priority is higher) */
+ int status; /* See above */
+
+ int restore_behavior;
+ int restore_time;
+
+ /* Grabbed from the sound iterator, for save/restore purposes */
+ int loops;
+ int hold;
+
+ song_iterator_t *it;
+ long delay; /* Delay before accessing the iterator, in microseconds */
+
+ GTimeVal wakeup_time; /* Used by the sound core:
+ ** Playing -> time at which 'delay' has elapsed
+ ** Suspended/Waiting -> stopping time */
+
+ struct _song *next; /* Next song or NULL if this is the last one */
+ struct _song *next_playing; /* Next playing song; used by the
+ ** core song system */
+ struct _song *next_stopping; /* Next song pending stopping; used exclusively by
+ ** the core song system's _update_multi_song() */
+} song_t;
+
+
+typedef struct {
+ song_t **lib;
+ song_t *_s;
+} songlib_t;
+
+/**************************/
+/* Song library commands: */
+/**************************/
+
+song_t *song_new(song_handle_t handle, song_iterator_t *it, int priority);
+/* Initializes a new song
+** Parameters: (song_handle_t) handle: The sound handle
+** (song_iterator_t *) it: The song
+** (int) priority: The song's priority
+** Returns : (song_t *) A freshly allocated song
+** Other values are set to predefined defaults.
+*/
+
+
+void song_lib_init(songlib_t *songlib);
+/* Initializes a static song library
+** Parameters: (songlib_t *) songlib: Pointer to the library
+** to initialize
+** Returns : (void)
+*/
+
+void song_lib_free(songlib_t songlib);
+/* Frees a song library
+** Parameters: (songlib_t) songlib: The library to free
+** Returns : (void)
+*/
+
+void song_lib_add(songlib_t songlib, song_t *song);
+/* Adds a song to a song library.
+** Parameters: (songlib_t) songlib: An existing sound library, or NULL
+** (song_t *) song: The song to add
+** Returns : (void)
+*/
+
+song_t *song_lib_find(songlib_t songlib, song_handle_t handle);
+/* Looks up the song with the specified handle
+** Parameters: (songlib_t) songlib: An existing sound library, may point to NULL
+** (song_handle_t) handle: The sound handle to look for
+** Returns : (song_t *) The song or NULL if it wasn't found
+*/
+
+song_t *song_lib_find_active(songlib_t songlib);
+/* Finds the first song playing with the highest priority
+** Parameters: (songlib_t) songlib: An existing sound library
+** Returns : (song_t *) The song that should be played next, or NULL if there is none
+*/
+
+song_t *song_lib_find_next_active(songlib_t songlib, song_t *song);
+/* Finds the next song playing with the highest priority
+** Parameters: (songlib_t) songlib: The song library to operate on
+** (song_t *) song: A song previously returned from the song library
+** Returns : (song_t *) The next song to play relative to 'song', or
+** NULL if none are left
+** The functions 'song_lib_find_active' and 'song_lib_find_next_active
+** allow to iterate over all songs that satisfy the requirement of
+** being 'playable'.
+*/
+
+int song_lib_remove(songlib_t songlib, song_handle_t handle);
+/* Removes a song from the library
+** Parameters: (songlib_t) songlib: An existing sound library
+** (song_handle_t) handle: Handle of the song to remove
+** Returns : (int) The status of the song that was removed
+*/
+
+void song_lib_resort(songlib_t songlib, song_t *song);
+/* Removes a song from the library and sorts it in again; for use after renicing
+** Parameters: (songlib_t) songlib: An existing sound library
+** (song_t *) song: The song to work on
+** Returns : (void)
+*/
+
+int song_lib_count(songlib_t songlib);
+/* Counts the number of songs in a song library
+** Parameters: (songlib_t) songlib: The library to count
+** Returns : (int) The number of songs
+*/
+
+GTimeVal song_sleep_time(GTimeVal *lastslept, long ticks);
+/* Caluculates the amount of seconds and microseconds to sleep.
+** Parameters: (GTimeVal *) lastslept: The time to start counting on
+** (long) ticks: Number of ticks to sleep
+** Returns : (GTimeVal) The amount of time to sleep
+*/
+
+GTimeVal song_next_wakeup_time(GTimeVal *lastslept, long ticks);
+/* Calculates the time at which "ticks" have passed, counting from "lastslept".
+** Parameters: (GTimeVal *) lastslept: The base to start counting on
+** (long) ticks: Number of ticks to count
+** Returns : (GTimeVal) A structure describing the time at which the
+** specified number of ticks has passed
+*/
+
+void song_lib_set_restore_behavior(songlib_t songlib, song_handle_t handle,
+ RESTORE_BEHAVIOR action);
+/* Determines what should be done with the song "handle" when
+** restoring it from a saved game.
+** Parameters: (songlib_t) songlib: The library that contains the song
+** (song_handle_t) handle: Its handle
+** (RESTORE_BEHAVIOR) action: The desired action
+*/
+
+} // End of namespace Sci
+
+#endif /* !_SCI_SOUND_SERVER_H_ */
diff --git a/engines/sci/sfx/sfx_time.h b/engines/sci/sfx/sfx_time.h
new file mode 100644
index 0000000000..d362dfa381
--- /dev/null
+++ b/engines/sci/sfx/sfx_time.h
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _SFX_TIME_H_
+#define _SFX_TIME_H_
+
+namespace Sci {
+
+typedef struct {
+ long secs;
+ long usecs;
+ int frame_rate;
+ int frame_offset;
+ /* Total time: secs + usecs + frame_offset/frame_rate */
+} sfx_timestamp_t;
+
+
+sfx_timestamp_t sfx_new_timestamp(long secs, long usecs, int frame_rate);
+/* Creates a new mutable timestamp
+** Parameters: (long x long) (secs, usecs): Initial timestamp
+** (int) frame_rate: Frame rate, for increasing the time stamp
+*/
+
+sfx_timestamp_t sfx_timestamp_add(sfx_timestamp_t timestamp, int frames);
+/* Adds a number of frames to a timestamp
+** Parameters: (sfx_timestampt_t *) timestamp: The timestamp to update
+** (int) frames: Number of frames to add
+** Returns : (sfx_timestamp_t) The increased timestamp
+*/
+
+sfx_timestamp_t sfx_timestamp_renormalise(sfx_timestamp_t timestamp, int new_freq);
+/* Translates a timestamp to a new base frame frequency
+** Parameters: (sfx_timestamp_t *) timestamp: The timestamp to normalise
+** (int) new_freq: The new frequency to normalise to
+** Returns : (sfx_timestamp_t) The re-normalised timestamp
+** The translation looses accuracy in the order of magnitude of milliseconds
+** for "usual" sampling frequencies.
+*/
+
+int sfx_timestamp_frame_diff(sfx_timestamp_t a, sfx_timestamp_t b);
+/* Computes the difference (# of frames) between two timestamps
+** Parameters: (sfx_timestamp) a: See below
+** (sfx_timestamp) b: See below
+** Returns : (int) a-b
+*/
+
+long sfx_timestamp_usecs_diff(sfx_timestamp_t a, sfx_timestamp_t b);
+/* Computes the difference (# of microseconds) between two timestamps
+** Parameters: (sfx_timestamp) a: See below
+** (sfx_timestamp) b: See below
+** Returns : (long) a-b
+*/
+
+void sfx_timestamp_gettime(sfx_timestamp_t *timestamp, long *secs, long *usecs);
+/* Determines the time described by a given timestamp
+** Parameters: (sfx_timestamp_t *) timestamp: Timestamp to read from
+** Returns : (int * x int *) (secs, usecs): Seconds and microseconds since
+** the epoch described there
+*/
+
+} // End of namespace Sci
+
+#endif /* !defined(_SFX_TIME_H_) */
diff --git a/engines/sci/sfx/sfx_timer.h b/engines/sci/sfx/sfx_timer.h
new file mode 100644
index 0000000000..581f7d1ac5
--- /dev/null
+++ b/engines/sci/sfx/sfx_timer.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef _FREESCI_SFX_TIMER_H_
+#define _FREESCI_SFX_TIMER_H_
+
+#include "sci/sfx/sfx_core.h"
+
+namespace Sci {
+
+typedef struct {
+ int delay_ms; /* Approximate delay (in milliseconds) between calls */
+
+ int (*init)(void (*callback)(void *data), void *data);
+ /* Initializes the timer
+ ** Parameters: (void* -> void) callback:
+ ** 'data' must contain the next argument:
+ ** (void *) data: Must always be passed to the callback
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** This does not start the timer yet, it just specifies and initializes it.
+ ** This function is called exactly once (provided that the timer is used at all).
+ */
+
+ int (*exit)();
+ /* Stops the timer
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** All resources allocated with the timer should be freed as an effect
+ ** of this.
+ */
+} sfx_timer_t;
+
+} // End of namespace Sci
+
+#endif /* !_FREESCI_SFX_TIMER_H_ */
diff --git a/engines/sci/sfx/softseq.h b/engines/sci/sfx/softseq.h
index 91c50ff3ec..5a2def8f41 100644
--- a/engines/sci/sfx/softseq.h
+++ b/engines/sci/sfx/softseq.h
@@ -26,8 +26,8 @@
#ifndef SCI_SFX_SOFTSEQ_H
#define SCI_SFX_SOFTSEQ_H
-#include "sci/include/sfx_core.h"
-#include "sci/include/sfx_pcm.h"
+#include "sci/sfx/sfx_core.h"
+#include "sci/sfx/sfx_pcm.h"
#include "sci/sfx/sequencer.h"
#include "sci/tools.h"
diff --git a/engines/sci/sfx/softseq/opl2.cpp b/engines/sci/sfx/softseq/opl2.cpp
index 1de9bd4659..81a0d13fc3 100644
--- a/engines/sci/sfx/softseq/opl2.cpp
+++ b/engines/sci/sfx/softseq/opl2.cpp
@@ -43,7 +43,7 @@
***************************************************************************/
#include "sci/tools.h"
-#include "sci/include/sfx_iterator.h"
+#include "sci/sfx/sfx_iterator.h"
#include "../softseq.h"
#include "../adlib.h"
#include <math.h>
diff --git a/engines/sci/sfx/songlib.cpp b/engines/sci/sfx/songlib.cpp
index 4adc1efa25..d98e387a96 100644
--- a/engines/sci/sfx/songlib.cpp
+++ b/engines/sci/sfx/songlib.cpp
@@ -24,7 +24,7 @@
*/
#include <stdio.h>
-#include "sci/include/sfx_engine.h"
+#include "sci/sfx/sfx_engine.h"
#include "sci/include/sci_memory.h"
namespace Sci {
diff --git a/engines/sci/sfx/time.cpp b/engines/sci/sfx/time.cpp
index 418343584a..720c233968 100644
--- a/engines/sci/sfx/time.cpp
+++ b/engines/sci/sfx/time.cpp
@@ -23,7 +23,7 @@
*
*/
-#include "sci/include/sfx_time.h"
+#include "sci/sfx/sfx_time.h"
#include "sci/tools.h"
namespace Sci {
diff --git a/engines/sci/sfx/timer.cpp b/engines/sci/sfx/timer.cpp
index ba2453579d..d58de323cd 100644
--- a/engines/sci/sfx/timer.cpp
+++ b/engines/sci/sfx/timer.cpp
@@ -25,7 +25,7 @@
#include "common/timer.h"
#include "engines/engine.h"
-#include "sci/include/sfx_timer.h"
+#include "sci/sfx/sfx_timer.h"
namespace Sci {