diff options
Diffstat (limited to 'engines/sci/sfx')
-rw-r--r-- | engines/sci/sfx/core.cpp | 6 | ||||
-rw-r--r-- | engines/sci/sfx/iterator.cpp | 4 | ||||
-rw-r--r-- | engines/sci/sfx/mixer.h | 2 | ||||
-rw-r--r-- | engines/sci/sfx/pcm-iterator.cpp | 2 | ||||
-rw-r--r-- | engines/sci/sfx/pcm_device.cpp | 4 | ||||
-rw-r--r-- | engines/sci/sfx/player/players.cpp | 2 | ||||
-rw-r--r-- | engines/sci/sfx/player/polled.cpp | 2 | ||||
-rw-r--r-- | engines/sci/sfx/player/realtime.cpp | 2 | ||||
-rw-r--r-- | engines/sci/sfx/sequencer.h | 2 | ||||
-rw-r--r-- | engines/sci/sfx/sfx_core.h | 40 | ||||
-rw-r--r-- | engines/sci/sfx/sfx_engine.h | 166 | ||||
-rw-r--r-- | engines/sci/sfx/sfx_iterator.h | 350 | ||||
-rw-r--r-- | engines/sci/sfx/sfx_iterator_internal.h | 236 | ||||
-rw-r--r-- | engines/sci/sfx/sfx_pcm.h | 184 | ||||
-rw-r--r-- | engines/sci/sfx/sfx_player.h | 154 | ||||
-rw-r--r-- | engines/sci/sfx/sfx_songlib.h | 191 | ||||
-rw-r--r-- | engines/sci/sfx/sfx_time.h | 85 | ||||
-rw-r--r-- | engines/sci/sfx/sfx_timer.h | 56 | ||||
-rw-r--r-- | engines/sci/sfx/softseq.h | 4 | ||||
-rw-r--r-- | engines/sci/sfx/softseq/opl2.cpp | 2 | ||||
-rw-r--r-- | engines/sci/sfx/songlib.cpp | 2 | ||||
-rw-r--r-- | engines/sci/sfx/time.cpp | 2 | ||||
-rw-r--r-- | engines/sci/sfx/timer.cpp | 2 |
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 { |