SCI: Turned sfx_player_t into a class SfxPlayer, and converted the existing players to subclasses of that

svn-id: r40912
This commit is contained in:
Max Horn 2009-05-26 11:49:10 +00:00
parent c5539b4e4e
commit 1d00cc5df0
10 changed files with 138 additions and 192 deletions

View file

@ -64,7 +64,6 @@ MODULE_OBJS = \
sfx/songlib.o \ sfx/songlib.o \
sfx/device/devices.o \ sfx/device/devices.o \
sfx/player/new_player.o \ sfx/player/new_player.o \
sfx/player/players.o \
sfx/player/polled.o \ sfx/player/polled.o \
sfx/player/realtime.o \ sfx/player/realtime.o \
sfx/seq/gm.o \ sfx/seq/gm.o \

View file

@ -27,7 +27,9 @@
#include "sci/tools.h" #include "sci/tools.h"
#include "sci/sfx/core.h" #include "sci/sfx/core.h"
#include "sci/sfx/player.h" #include "sci/sfx/player/new_player.h"
#include "sci/sfx/player/polled.h"
#include "sci/sfx/player/realtime.h"
#include "sci/sfx/sci_midi.h" #include "sci/sfx/sci_midi.h"
#include "common/system.h" #include "common/system.h"
@ -44,7 +46,7 @@ namespace Sci {
int sciprintf(char *msg, ...); int sciprintf(char *msg, ...);
#endif #endif
static sfx_player_t *player = NULL; SfxPlayer *player = NULL; // FIXME: Avoid static vars
int sfx_pcm_available() { int sfx_pcm_available() {
@ -56,13 +58,6 @@ void sfx_reset_player() {
player->stop(); player->stop();
} }
tell_synth_func *sfx_get_player_tell_func() {
if (player)
return player->tell_synth;
else
return NULL;
}
int sfx_get_player_polyphony() { int sfx_get_player_polyphony() {
if (player) if (player)
return player->polyphony; return player->polyphony;
@ -306,8 +301,7 @@ static void _update_multi_song(sfx_state_t *self) {
sciprintf("[SFX] Stopping song %lx\n", oldseeker->handle); sciprintf("[SFX] Stopping song %lx\n", oldseeker->handle);
} }
if (player && oldseeker->it) if (player && oldseeker->it)
player->iterator_message player->iterator_message(SongIterator::Message(oldseeker->it->ID, SIMSG_STOP));
(SongIterator::Message(oldseeker->it->ID, SIMSG_STOP));
oldseeker->next_playing = NULL; /* Clear this pointer; we don't need the tag anymore */ oldseeker->next_playing = NULL; /* Clear this pointer; we don't need the tag anymore */
} }
@ -352,7 +346,6 @@ int sfx_play_iterator_pcm(SongIterator *it, song_handle_t handle) {
#define DELAY (1000000 / SFX_TICKS_PER_SEC) #define DELAY (1000000 / SFX_TICKS_PER_SEC)
static void _sfx_timer_callback(void *data) { static void _sfx_timer_callback(void *data) {
/* First run the player, to give it a chance to fill /* First run the player, to give it a chance to fill
** the audio buffer */ ** the audio buffer */
@ -375,7 +368,10 @@ void sfx_init(sfx_state_t *self, ResourceManager *resmgr, int flags) {
return; return;
} }
player = sfx_find_player(NULL); // TODO: Implement platform policy here?
player = new NewPlayer();
//player = new PolledPlayer();
//player = new RealtimePlayer();
#ifdef DEBUG_SONG_API #ifdef DEBUG_SONG_API
@ -391,6 +387,7 @@ void sfx_init(sfx_state_t *self, ResourceManager *resmgr, int flags) {
player = NULL; player = NULL;
} else if (player->init(resmgr, DELAY / 1000)) { } else if (player->init(resmgr, DELAY / 1000)) {
sciprintf("[SFX] Song player '%s' reported error, disabled\n", player->name); sciprintf("[SFX] Song player '%s' reported error, disabled\n", player->name);
delete player;
player = NULL; player = NULL;
} }
@ -406,16 +403,15 @@ void sfx_init(sfx_state_t *self, ResourceManager *resmgr, int flags) {
// We initialise the timer last, so there is no possibility of the // We initialise the timer last, so there is no possibility of the
// timer callback being triggered while the mixer or player are // timer callback being triggered while the mixer or player are
// still being initialized. // still being initialized.
if (strcmp(player->name, "realtime") == 0) {
if (g_system->getMixer()->isReady() || (player && player->maintenance)) { // FIXME: Merge this timer code into RealtimePlayer itself
if (!g_system->getTimerManager()->installTimerProc(&_sfx_timer_callback, DELAY, NULL)) { if (!g_system->getTimerManager()->installTimerProc(&_sfx_timer_callback, DELAY, NULL)) {
warning("[SFX] " __FILE__": Timer failed to initialize"); warning("[SFX] " __FILE__": Timer failed to initialize");
warning("[SFX] Disabled sound support"); warning("[SFX] Disabled sound support");
delete player;
player = NULL; player = NULL;
return;
} }
} /* With no PCM device and no player, we don't need a timer */ }
} }
void sfx_exit(sfx_state_t *self) { void sfx_exit(sfx_state_t *self) {
@ -429,8 +425,6 @@ void sfx_exit(sfx_state_t *self) {
fprintf(stderr, "[sfx-core] Uninitialising\n"); fprintf(stderr, "[sfx-core] Uninitialising\n");
#endif #endif
song_lib_free(self->songlib);
// WARNING: The mixer may hold feeds from the player, so we must // WARNING: The mixer may hold feeds from the player, so we must
// stop the mixer BEFORE stopping the player. // stop the mixer BEFORE stopping the player.
// FIXME Player "new" frees its own feeds, so we only need to stop any // FIXME Player "new" frees its own feeds, so we only need to stop any
@ -438,13 +432,19 @@ void sfx_exit(sfx_state_t *self) {
if (strcmp(player->name, "new") != 0) if (strcmp(player->name, "new") != 0)
g_system->getMixer()->stopAll(); g_system->getMixer()->stopAll();
if (player) // FIXME: change players to stop their own audio streams
if (player) {
// See above: This must happen AFTER stopping the mixer // See above: This must happen AFTER stopping the mixer
player->exit(); player->exit();
delete player;
player = 0;
}
if (strcmp(player->name, "new") == 0) if (strcmp(player->name, "new") == 0)
g_system->getMixer()->stopAll(); g_system->getMixer()->stopAll();
song_lib_free(self->songlib);
// Delete audio resources for CD talkie games // Delete audio resources for CD talkie games
if (self->audioResource) { if (self->audioResource) {
delete self->audioResource; delete self->audioResource;
@ -715,7 +715,6 @@ static const song_handle_t midi_send_base = 0xffff0000;
Common::Error sfx_send_midi(sfx_state_t *self, song_handle_t handle, int channel, Common::Error sfx_send_midi(sfx_state_t *self, song_handle_t handle, int channel,
int command, int arg1, int arg2) { int command, int arg1, int arg2) {
byte buffer[5]; byte buffer[5];
tell_synth_func *tell = sfx_get_player_tell_func();
/* Yes, in that order. SCI channel mutes are actually done via /* Yes, in that order. SCI channel mutes are actually done via
a counting semaphore. 0 means to decrement the counter, 1 a counting semaphore. 0 means to decrement the counter, 1
@ -753,8 +752,8 @@ Common::Error sfx_send_midi(sfx_state_t *self, song_handle_t handle, int channel
return Common::kUnknownError; return Common::kUnknownError;
} }
if (tell) if (player)
tell(MIDI_cmdlen[command >> 4], buffer); player->tell_synth(MIDI_cmdlen[command >> 4], buffer);
return Common::kNoError; return Common::kNoError;
} }

View file

@ -127,22 +127,22 @@ void SongIteratorChannel::init(int id_, int offset_, int end_) {
} }
void SongIteratorChannel::resetSynthChannels() { void SongIteratorChannel::resetSynthChannels() {
extern SfxPlayer *player; // FIXME
byte buf[5]; byte buf[5];
tell_synth_func *tell = sfx_get_player_tell_func();
for (int i = 0; i < MIDI_CHANNELS; i++) { for (int i = 0; i < MIDI_CHANNELS; i++) {
if (playmask & (1 << i)) { if (playmask & (1 << i)) {
buf[0] = 0xe0 | i; /* Pitch bend */ buf[0] = 0xe0 | i; /* Pitch bend */
buf[1] = 0x80; /* Wheel center */ buf[1] = 0x80; /* Wheel center */
buf[2] = 0x40; buf[2] = 0x40;
if (tell) if (player)
tell(3, buf); player->tell_synth(3, buf);
buf[0] = 0xb0 | i; // Set control buf[0] = 0xb0 | i; // Set control
buf[1] = 0x40; // Hold pedal buf[1] = 0x40; // Hold pedal
buf[2] = 0x00; // Off buf[2] = 0x00; // Off
if (tell) if (player)
tell(3, buf); player->tell_synth(3, buf);
/* TODO: Reset other controls? */ /* TODO: Reset other controls? */
} }
} }

View file

@ -35,20 +35,19 @@
namespace Sci { namespace Sci {
typedef void tell_synth_func(int buf_nr, byte *buf); class SfxPlayer {
public:
struct sfx_player_t {
const char *name; const char *name;
const char *version; const char *version;
Common::Error (*set_option)(char *name, char *value); /** Number of voices that can play simultaneously */
/* Sets an option for player timing mechanism int polyphony;
** Parameters: (char *) name: The name describing what to set
** (char *) value: The value to set
** Returns : (int) Common::kNoError, or Common::kUnknownError if the name wasn't understood
*/
Common::Error (*init)(ResourceManager *resmgr, int expected_latency); public:
SfxPlayer() : name(0), version(0), polyphony(0) {}
virtual ~SfxPlayer() {}
virtual Common::Error init(ResourceManager *resmgr, int expected_latency) = 0;
/* Initializes the player /* Initializes the player
** Parameters: (ResourceManager *) resmgr: A resource manager for driver initialization ** Parameters: (ResourceManager *) resmgr: A resource manager for driver initialization
** (int) expected_latency: Expected delay in between calls to 'maintenance' ** (int) expected_latency: Expected delay in between calls to 'maintenance'
@ -56,7 +55,7 @@ struct sfx_player_t {
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure ** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
*/ */
Common::Error (*add_iterator)(SongIterator *it, uint32 start_time); virtual Common::Error add_iterator(SongIterator *it, uint32 start_time) = 0;
/* Adds an iterator to the song player /* Adds an iterator to the song player
** Parameters: (songx_iterator_t *) it: The iterator to play ** Parameters: (songx_iterator_t *) it: The iterator to play
** (uint32) start_time: The time to assume as the ** (uint32) start_time: The time to assume as the
@ -68,17 +67,12 @@ struct sfx_player_t {
** to add iterators onto their already existing iterators ** to add iterators onto their already existing iterators
*/ */
Common::Error (*fade_out)(); virtual Common::Error stop() = 0;
/* Fades out the currently playing song (within two seconds
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
*/
Common::Error (*stop)();
/* Stops the currently playing song and deletes the associated iterator /* Stops the currently playing song and deletes the associated iterator
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure ** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
*/ */
Common::Error (*iterator_message)(const SongIterator::Message &msg); virtual Common::Error iterator_message(const SongIterator::Message &msg) = 0;
/* Transmits a song iterator message to the active song /* Transmits a song iterator message to the active song
** Parameters: (SongIterator::Message) msg: The message to transmit ** Parameters: (SongIterator::Message) msg: The message to transmit
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure ** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
@ -87,48 +81,34 @@ struct sfx_player_t {
** and re-start playing, so it is preferred that it is present ** and re-start playing, so it is preferred that it is present
*/ */
Common::Error (*pause)(); /* OPTIONAL -- may be NULL */ virtual Common::Error pause() = 0;
/* Pauses song playing /* Pauses song playing
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure ** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
*/ */
Common::Error (*resume)(); /* OPTIONAL -- may be NULL */ virtual Common::Error resume() = 0;
/* Resumes song playing after a pause /* Resumes song playing after a pause
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure ** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
*/ */
Common::Error (*exit)(); virtual Common::Error exit() = 0;
/* Stops the player /* Stops the player
** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure ** Returns : (int) Common::kNoError on success, Common::kUnknownError on failure
*/ */
void (*maintenance)(); /* OPTIONAL -- may be NULL */ virtual void maintenance() {}
/* Regularly called maintenance function /* Regularly called maintenance function
** This function is called frequently and regularly (if present), it can be ** This function is called frequently and regularly (if present), it can be
** used to emit sound. ** used to emit sound.
*/ */
tell_synth_func *tell_synth; virtual void tell_synth(int buf_nr, byte *buf) = 0;
/* Pass a raw MIDI event to the synth /* Pass a raw MIDI event to the synth
Parameters: (int) argc: Length of buffer holding the midi event Parameters: (int) argc: Length of buffer holding the midi event
(byte *) argv: The buffer itself (byte *) argv: The buffer itself
*/ */
int polyphony; /* Number of voices that can play simultaneously */
}; };
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(); int sfx_get_player_polyphony();
/* Determines the polyphony of the player in use /* Determines the polyphony of the player in use
** Returns : (int) Number of voices the active player can emit ** Returns : (int) Number of voices the active player can emit

View file

@ -36,6 +36,7 @@
namespace Sci { namespace Sci {
// TODO: Turn the following static vars into member vars
static MidiPlayer *mididrv; static MidiPlayer *mididrv;
static SongIterator *play_it = NULL; static SongIterator *play_it = NULL;
@ -89,7 +90,7 @@ static void play_song(SongIterator *it) {
} }
} }
static void player_tell_synth(int buf_nr, byte *buf) { void NewPlayer::tell_synth(int buf_nr, byte *buf) {
byte op1 = (buf_nr < 2 ? 0 : buf[1]); byte op1 = (buf_nr < 2 ? 0 : buf[1]);
byte op2 = (buf_nr < 3 ? 0 : buf[2]); byte op2 = (buf_nr < 3 ? 0 : buf[2]);
@ -97,25 +98,18 @@ static void player_tell_synth(int buf_nr, byte *buf) {
} }
static void player_timer_callback(void *refCon) { static void player_timer_callback(void *refCon) {
mutex->lock(); Common::StackLock lock(*mutex);
if (play_it && !play_it_done && !play_paused) { if (play_it && !play_it_done && !play_paused) {
play_song(play_it); play_song(play_it);
} }
current_time = current_time.addFrames(1); current_time = current_time.addFrames(1);
mutex->unlock();
}
static void player_void_callback(void) {
} }
/* API implementation */ /* API implementation */
static Common::Error player_set_option(char *name, char *value) { Common::Error NewPlayer::init(ResourceManager *resmgr, int expected_latency) {
return Common::kUnknownError;
}
static Common::Error player_init(ResourceManager *resmgr, int expected_latency) {
MidiDriverType musicDriver = MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_ADLIB); MidiDriverType musicDriver = MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_ADLIB);
switch(musicDriver) { switch(musicDriver) {
@ -134,7 +128,7 @@ static Common::Error player_init(ResourceManager *resmgr, int expected_latency)
assert(mididrv); assert(mididrv);
sfx_new_player.polyphony = mididrv->getPolyphony(); this->polyphony = mididrv->getPolyphony();
tempo = mididrv->getBaseTempo(); tempo = mididrv->getBaseTempo();
uint32 time = g_system->getMillis(); uint32 time = g_system->getMillis();
@ -150,7 +144,7 @@ static Common::Error player_init(ResourceManager *resmgr, int expected_latency)
return Common::kNoError; return Common::kNoError;
} }
static Common::Error player_add_iterator(SongIterator *it, uint32 start_time) { Common::Error NewPlayer::add_iterator(SongIterator *it, uint32 start_time) {
mutex->lock(); mutex->lock();
SIMSG_SEND(it, SIMSG_SET_PLAYMASK(mididrv->getPlayMask())); SIMSG_SEND(it, SIMSG_SET_PLAYMASK(mididrv->getPlayMask()));
SIMSG_SEND(it, SIMSG_SET_RHYTHM(mididrv->hasRhythmChannel())); SIMSG_SEND(it, SIMSG_SET_RHYTHM(mididrv->hasRhythmChannel()));
@ -168,12 +162,7 @@ static Common::Error player_add_iterator(SongIterator *it, uint32 start_time) {
return Common::kNoError; return Common::kNoError;
} }
static Common::Error player_fade_out(void) { Common::Error NewPlayer::stop(void) {
warning("Attempt to fade out - not implemented yet");
return Common::kUnknownError;
}
static Common::Error player_stop(void) {
debug(3, "Player: Stopping song iterator %p", (void *)play_it); debug(3, "Player: Stopping song iterator %p", (void *)play_it);
mutex->lock(); mutex->lock();
delete play_it; delete play_it;
@ -185,41 +174,39 @@ static Common::Error player_stop(void) {
return Common::kNoError; return Common::kNoError;
} }
static Common::Error player_send_iterator_message(const SongIterator::Message &msg) { Common::Error NewPlayer::iterator_message(const SongIterator::Message &msg) {
mutex->lock(); Common::StackLock lock(*mutex);
if (!play_it) { if (!play_it) {
mutex->unlock();
return Common::kUnknownError; return Common::kUnknownError;
} }
songit_handle_message(&play_it, msg); songit_handle_message(&play_it, msg);
mutex->unlock();
return Common::kNoError; return Common::kNoError;
} }
static Common::Error player_pause(void) { Common::Error NewPlayer::pause(void) {
mutex->lock(); Common::StackLock lock(*mutex);
play_paused = 1; play_paused = 1;
play_pause_diff = wakeup_time.msecsDiff(current_time); play_pause_diff = wakeup_time.msecsDiff(current_time);
mididrv->playSwitch(false); mididrv->playSwitch(false);
mutex->unlock();
return Common::kNoError; return Common::kNoError;
} }
static Common::Error player_resume(void) { Common::Error NewPlayer::resume(void) {
mutex->lock(); Common::StackLock lock(*mutex);
wakeup_time = Audio::Timestamp(current_time.msecs() + play_pause_diff, SFX_TICKS_PER_SEC); wakeup_time = Audio::Timestamp(current_time.msecs() + play_pause_diff, SFX_TICKS_PER_SEC);
mididrv->playSwitch(true); mididrv->playSwitch(true);
play_paused = 0; play_paused = 0;
mutex->unlock();
return Common::kNoError; return Common::kNoError;
} }
static Common::Error player_exit(void) { Common::Error NewPlayer::exit(void) {
mididrv->close(); mididrv->close();
delete mididrv; delete mididrv;
delete mutex; delete mutex;
@ -229,22 +216,9 @@ static Common::Error player_exit(void) {
return Common::kNoError; return Common::kNoError;
} }
sfx_player_t sfx_new_player = { NewPlayer::NewPlayer() {
"new", name = "new";
"0.1", version = "0.1";
&player_set_option, }
&player_init,
&player_add_iterator,
&player_fade_out,
&player_stop,
&player_send_iterator_message,
&player_pause,
&player_resume,
&player_exit,
&player_void_callback,
&player_tell_synth,
0 /* polyphony */
};
} // End of namespace Sci } // End of namespace Sci

View file

@ -30,7 +30,19 @@
namespace Sci { namespace Sci {
extern sfx_player_t sfx_new_player; class NewPlayer : public SfxPlayer {
public:
NewPlayer();
virtual Common::Error init(ResourceManager *resmgr, int expected_latency);
virtual Common::Error add_iterator(SongIterator *it, uint32 start_time);
virtual Common::Error stop();
virtual Common::Error iterator_message(const SongIterator::Message &msg);
virtual Common::Error pause();
virtual Common::Error resume();
virtual Common::Error exit();
virtual void tell_synth(int buf_nr, byte *buf);
};
} // End of namespace Sci } // End of namespace Sci

View file

@ -36,6 +36,7 @@
namespace Sci { namespace Sci {
// TODO: Turn the following static vars into member vars
static SongIterator *play_it; static SongIterator *play_it;
static int play_paused = 0; static int play_paused = 0;
static sfx_softseq_t *seq; static sfx_softseq_t *seq;
@ -48,7 +49,7 @@ static int new_song = 0;
#define TIME_INC 60 #define TIME_INC 60
static int time_counter = 0; static int time_counter = 0;
static void pp_tell_synth(int buf_nr, byte *buf) { void PolledPlayer::tell_synth(int buf_nr, byte *buf) {
seq->handle_command(seq, buf[0], buf_nr - 1, buf + 1); seq->handle_command(seq, buf[0], buf_nr - 1, buf + 1);
} }
@ -262,15 +263,7 @@ static int ppf_poll(int frame_size, byte *dest, int size) {
/* API implementation */ /* API implementation */
/*--------------------*/ /*--------------------*/
static void pp_timer_callback() { Common::Error PolledPlayer::init(ResourceManager *resmgr, int expected_latency) {
/* Hey, we're polled anyway ;-) */
}
static Common::Error pp_set_option(char *name, char *value) {
return Common::kUnknownError;
}
static Common::Error pp_init(ResourceManager *resmgr, int expected_latency) {
if (!g_system->getMixer()->isReady()) if (!g_system->getMixer()->isReady())
return Common::kUnknownError; return Common::kUnknownError;
@ -307,15 +300,16 @@ static Common::Error pp_init(ResourceManager *resmgr, int expected_latency) {
seq->set_volume(seq, volume); seq->set_volume(seq, volume);
// FIXME: Keep a SoundHandle and use that to stop the feed in the exit method
PolledPlayerAudioStream *newStream = new PolledPlayerAudioStream(seq->pcm_conf); PolledPlayerAudioStream *newStream = new PolledPlayerAudioStream(seq->pcm_conf);
// FIXME: Is this sound type appropriate? // FIXME: Is this sound type appropriate?
g_system->getMixer()->playInputStream(Audio::Mixer::kSFXSoundType, 0, newStream); g_system->getMixer()->playInputStream(Audio::Mixer::kSFXSoundType, 0, newStream);
sfx_player_polled.polyphony = seq->polyphony; this->polyphony = seq->polyphony;
return Common::kNoError; return Common::kNoError;
} }
static Common::Error pp_add_iterator(SongIterator *it, uint32 start_time) { Common::Error PolledPlayer::add_iterator(SongIterator *it, uint32 start_time) {
SongIterator *old = play_it; SongIterator *old = play_it;
SIMSG_SEND(it, SIMSG_SET_PLAYMASK(seq->playmask)); SIMSG_SEND(it, SIMSG_SET_PLAYMASK(seq->playmask));
@ -340,12 +334,7 @@ static Common::Error pp_add_iterator(SongIterator *it, uint32 start_time) {
return Common::kNoError; return Common::kNoError;
} }
static Common::Error pp_fade_out() { Common::Error PolledPlayer::stop() {
warning(__FILE__": Attempt to fade out- not implemented yet");
return Common::kUnknownError;
}
static Common::Error pp_stop() {
SongIterator *it = play_it; SongIterator *it = play_it;
play_it = NULL; play_it = NULL;
@ -357,7 +346,7 @@ static Common::Error pp_stop() {
return Common::kNoError; return Common::kNoError;
} }
static Common::Error pp_send_iterator_message(const SongIterator::Message &msg) { Common::Error PolledPlayer::iterator_message(const SongIterator::Message &msg) {
if (!play_it) if (!play_it)
return Common::kUnknownError; return Common::kUnknownError;
@ -365,14 +354,14 @@ static Common::Error pp_send_iterator_message(const SongIterator::Message &msg)
return Common::kNoError; return Common::kNoError;
} }
static Common::Error pp_pause() { Common::Error PolledPlayer::pause() {
play_paused = 1; play_paused = 1;
seq->set_volume(seq, 0); seq->set_volume(seq, 0);
return Common::kNoError; return Common::kNoError;
} }
static Common::Error pp_resume() { Common::Error PolledPlayer::resume() {
if (!play_it) { if (!play_it) {
play_paused = 0; play_paused = 0;
return Common::kNoError; /* Nothing to resume */ return Common::kNoError; /* Nothing to resume */
@ -388,7 +377,7 @@ static Common::Error pp_resume() {
return Common::kNoError; return Common::kNoError;
} }
static Common::Error pp_exit() { Common::Error PolledPlayer::exit() {
seq->exit(seq); seq->exit(seq);
delete play_it; delete play_it;
play_it = NULL; play_it = NULL;
@ -396,21 +385,9 @@ static Common::Error pp_exit() {
return Common::kNoError; return Common::kNoError;
} }
sfx_player_t sfx_player_polled = { PolledPlayer::PolledPlayer() {
"polled", name = "polled";
"0.1", version = "0.1";
&pp_set_option, }
&pp_init,
&pp_add_iterator,
&pp_fade_out,
&pp_stop,
&pp_send_iterator_message,
&pp_pause,
&pp_resume,
&pp_exit,
&pp_timer_callback,
&pp_tell_synth,
0 /* polyphony */
};
} // End of namespace Sci } // End of namespace Sci

View file

@ -30,7 +30,19 @@
namespace Sci { namespace Sci {
extern sfx_player_t sfx_player_polled; class PolledPlayer : public SfxPlayer {
public:
PolledPlayer();
virtual Common::Error init(ResourceManager *resmgr, int expected_latency);
virtual Common::Error add_iterator(SongIterator *it, uint32 start_time);
virtual Common::Error stop();
virtual Common::Error iterator_message(const SongIterator::Message &msg);
virtual Common::Error pause();
virtual Common::Error resume();
virtual Common::Error exit();
virtual void tell_synth(int buf_nr, byte *buf);
};
} // End of namespace Sci } // End of namespace Sci

View file

@ -37,14 +37,15 @@
namespace Sci { namespace Sci {
static sfx_sequencer_t *seq;
/* Playing mechanism */ /* Playing mechanism */
static inline int delta_time(const uint32 comp, const uint32 base) { static inline int delta_time(const uint32 comp, const uint32 base) {
return long(comp) - long(base); return long(comp) - long(base);
} }
// TODO: Turn the following static vars into member vars
static sfx_sequencer_t *seq;
static SongIterator *play_it = NULL; static SongIterator *play_it = NULL;
static uint32 play_last_time; static uint32 play_last_time;
static uint32 play_pause_started; /* Beginning of the last pause */ static uint32 play_pause_started; /* Beginning of the last pause */
@ -105,11 +106,11 @@ static void play_song(SongIterator *it, uint32 *wakeup_time, int writeahead_time
} }
} }
static void rt_tell_synth(int buf_nr, byte *buf) { void RealtimePlayer::tell_synth(int buf_nr, byte *buf) {
seq->event(buf[0], buf_nr - 1, buf + 1); seq->event(buf[0], buf_nr - 1, buf + 1);
} }
static void rt_timer_callback(void) { void RealtimePlayer::maintenance() {
if (play_it && !play_it_done) { if (play_it && !play_it_done) {
if (!play_moredelay) { if (!play_moredelay) {
int delta = delta_time(play_last_time, g_system->getMillis()); int delta = delta_time(play_last_time, g_system->getMillis());
@ -145,11 +146,7 @@ static Resource *find_patch(ResourceManager *resmgr, const char *seq_name, int p
/* API implementation */ /* API implementation */
static Common::Error rt_set_option(char *name, char *value) { Common::Error RealtimePlayer::init(ResourceManager *resmgr, int expected_latency) {
return Common::kUnknownError;
}
static Common::Error rt_init(ResourceManager *resmgr, int expected_latency) {
Resource *res = NULL, *res2 = NULL; Resource *res = NULL, *res2 = NULL;
void *seq_dev = NULL; void *seq_dev = NULL;
@ -160,7 +157,7 @@ static Common::Error rt_init(ResourceManager *resmgr, int expected_latency) {
return Common::kUnknownError; return Common::kUnknownError;
} }
sfx_player_realtime.polyphony = seq->polyphony; this->polyphony = seq->polyphony;
res = find_patch(resmgr, seq->name, seq->patchfile); res = find_patch(resmgr, seq->name, seq->patchfile);
res2 = find_patch(resmgr, seq->name, seq->patchfile2); res2 = find_patch(resmgr, seq->name, seq->patchfile2);
@ -189,7 +186,7 @@ static Common::Error rt_init(ResourceManager *resmgr, int expected_latency) {
return Common::kNoError; return Common::kNoError;
} }
static Common::Error rt_add_iterator(SongIterator *it, uint32 start_time) { Common::Error RealtimePlayer::add_iterator(SongIterator *it, uint32 start_time) {
if (seq->reset_timer) /* Restart timer counting if possible */ if (seq->reset_timer) /* Restart timer counting if possible */
seq->reset_timer(start_time); seq->reset_timer(start_time);
@ -204,12 +201,7 @@ static Common::Error rt_add_iterator(SongIterator *it, uint32 start_time) {
return Common::kNoError; return Common::kNoError;
} }
static Common::Error rt_fade_out(void) { Common::Error RealtimePlayer::stop(void) {
warning(__FILE__": Attempt to fade out- not implemented yet");
return Common::kUnknownError;
}
static Common::Error rt_stop(void) {
SongIterator *it = play_it; SongIterator *it = play_it;
play_it = NULL; play_it = NULL;
@ -221,7 +213,7 @@ static Common::Error rt_stop(void) {
return Common::kNoError; return Common::kNoError;
} }
static Common::Error rt_send_iterator_message(const SongIterator::Message &msg) { Common::Error RealtimePlayer::iterator_message(const SongIterator::Message &msg) {
if (!play_it) if (!play_it)
return Common::kUnknownError; return Common::kUnknownError;
@ -229,7 +221,7 @@ static Common::Error rt_send_iterator_message(const SongIterator::Message &msg)
return Common::kNoError; return Common::kNoError;
} }
static Common::Error rt_pause(void) { Common::Error RealtimePlayer::pause(void) {
play_pause_started = g_system->getMillis(); play_pause_started = g_system->getMillis();
// Also, indicate that we haven't modified the time counter yet // Also, indicate that we haven't modified the time counter yet
play_pause_counter = play_pause_started; play_pause_counter = play_pause_started;
@ -242,12 +234,12 @@ static Common::Error rt_pause(void) {
return seq->allstop(); return seq->allstop();
} }
static Common::Error rt_resume(void) { Common::Error RealtimePlayer::resume(void) {
play_paused = 0; play_paused = 0;
return Common::kNoError; return Common::kNoError;
} }
static Common::Error rt_exit(void) { Common::Error RealtimePlayer::exit(void) {
if (seq->close()) { if (seq->close()) {
warning("[SFX] Sequencer reported error on close"); warning("[SFX] Sequencer reported error on close");
return Common::kUnknownError; return Common::kUnknownError;
@ -256,21 +248,9 @@ static Common::Error rt_exit(void) {
return Common::kNoError; return Common::kNoError;
} }
sfx_player_t sfx_player_realtime = { RealtimePlayer::RealtimePlayer() {
"realtime", name = "realtime";
"0.1", version = "0.1";
&rt_set_option, }
&rt_init,
&rt_add_iterator,
&rt_fade_out,
&rt_stop,
&rt_send_iterator_message,
&rt_pause,
&rt_resume,
&rt_exit,
&rt_timer_callback,
&rt_tell_synth,
0 /* polyphony */
};
} // End of namespace Sci } // End of namespace Sci

View file

@ -30,7 +30,20 @@
namespace Sci { namespace Sci {
extern sfx_player_t sfx_player_realtime; class RealtimePlayer : public SfxPlayer {
public:
RealtimePlayer();
virtual Common::Error init(ResourceManager *resmgr, int expected_latency);
virtual Common::Error add_iterator(SongIterator *it, uint32 start_time);
virtual Common::Error stop();
virtual Common::Error iterator_message(const SongIterator::Message &msg);
virtual Common::Error pause();
virtual Common::Error resume();
virtual Common::Error exit();
virtual void maintenance();
virtual void tell_synth(int buf_nr, byte *buf);
};
} // End of namespace Sci } // End of namespace Sci