diff options
Diffstat (limited to 'engines/sci/sfx/sfx_iterator_internal.h')
-rw-r--r-- | engines/sci/sfx/sfx_iterator_internal.h | 236 |
1 files changed, 236 insertions, 0 deletions
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_ */ |