diff options
author | Walter van Niftrik | 2009-04-15 10:45:59 +0000 |
---|---|---|
committer | Walter van Niftrik | 2009-04-15 10:45:59 +0000 |
commit | 695bc36b9affeaaf2d2e635b0d72278915a3997b (patch) | |
tree | 4551d80b91b44fda90ceca2fd2b76d0a5f5ca367 /engines/sci/sfx/player | |
parent | 570f2c66b83425e88aab53979d2349aedb4ccc8b (diff) | |
download | scummvm-rg350-695bc36b9affeaaf2d2e635b0d72278915a3997b.tar.gz scummvm-rg350-695bc36b9affeaaf2d2e635b0d72278915a3997b.tar.bz2 scummvm-rg350-695bc36b9affeaaf2d2e635b0d72278915a3997b.zip |
SCI: Added a new song player (work-in-progress).
svn-id: r39953
Diffstat (limited to 'engines/sci/sfx/player')
-rw-r--r-- | engines/sci/sfx/player/player.cpp | 234 | ||||
-rw-r--r-- | engines/sci/sfx/player/players.cpp | 2 |
2 files changed, 236 insertions, 0 deletions
diff --git a/engines/sci/sfx/player/player.cpp b/engines/sci/sfx/player/player.cpp new file mode 100644 index 0000000000..ada2dc4357 --- /dev/null +++ b/engines/sci/sfx/player/player.cpp @@ -0,0 +1,234 @@ +/* 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$ + * + */ + +#include "sci/tools.h" +#include "sci/sfx/player.h" +#include "sci/sfx/sequencer.h" +#include "sci/sfx/iterator.h" +#include "sci/sfx/core.h" + +#include "common/system.h" + +#include "sci/sfx/softseq/pcjr.h" + +namespace Sci { + +extern sfx_player_t sfx_player_player; +static MidiPlayer *mididrv; + +static SongIterator *play_it = NULL; +static Audio::Timestamp wakeup_time; +static Audio::Timestamp current_time; +static uint32 play_pause_diff; + +static int play_paused = 0; +static int play_it_done = 0; +static uint32 tempo; + +static Common::Mutex *mutex; + +static void play_song(SongIterator *it) { + while (play_it && wakeup_time.msecsDiff(current_time) <= 0) { + int delay; + byte buf[8]; + int result; + + switch ((delay = songit_next(&(play_it), + buf, &result, + IT_READER_MASK_ALL + | IT_READER_MAY_FREE + | IT_READER_MAY_CLEAN))) { + + case SI_FINISHED: + play_it_done = 1; + return; + + case SI_IGNORE: + case SI_LOOP: + case SI_RELATIVE_CUE: + case SI_ABSOLUTE_CUE: + break; + + case SI_PCM: + sfx_play_iterator_pcm(play_it, 0); + break; + + case 0: + static_cast<MidiDriver *>(mididrv)->send(buf[0], buf[1], buf[2]); + + break; + + default: + wakeup_time = wakeup_time.addFrames(delay); + } + } +} + +static void player_tell_synth(int buf_nr, byte *buf) { + byte op1 = (buf_nr < 2 ? 0 : buf[1]); + byte op2 = (buf_nr < 3 ? 0 : buf[2]); + + static_cast<MidiDriver *>(mididrv)->send(buf[0], op1, op2); +} + +static void player_timer_callback(void *refCon) { + mutex->lock(); + if (play_it && !play_it_done && !play_paused) { + play_song(play_it); + } + + current_time = current_time.addFrames(1); + mutex->unlock(); +} + +static void player_void_callback(void) { +} + +/* API implementation */ + +static int player_set_option(char *name, char *value) { + return SFX_ERROR; +} + +static int player_init(ResourceManager *resmgr, int expected_latency) { + MidiDriverType musicDriver = MidiDriver::detectMusicDriver(MDT_PCSPK); + + switch(musicDriver) { + case MD_PCJR: + mididrv = new MidiPlayer_PCJr(); + break; + case MD_PCSPK: + mididrv = new MidiPlayer_PCSpeaker(); + break; + default: + break; + } + + assert(mididrv); + + sfx_player_player.polyphony = mididrv->getPolyphony(); + + tempo = mididrv->getBaseTempo(); + uint32 time = g_system->getMillis(); + current_time = Audio::Timestamp(time, 1000000 / tempo); + wakeup_time = Audio::Timestamp(time, SFX_TICKS_PER_SEC); + + mutex = new Common::Mutex(); + + mididrv->setTimerCallback(NULL, player_timer_callback); + mididrv->open(resmgr); + + return SFX_OK; +} + +static int player_add_iterator(SongIterator *it, uint32 start_time) { + mutex->lock(); + SIMSG_SEND(it, SIMSG_SET_PLAYMASK(mididrv->getPlayMask())); + SIMSG_SEND(it, SIMSG_SET_RHYTHM(mididrv->hasRhythmChannel())); + + current_time = Audio::Timestamp(g_system->getMillis(), 1000000 / tempo); + wakeup_time = Audio::Timestamp(start_time, SFX_TICKS_PER_SEC); + play_it = sfx_iterator_combine(play_it, it); + play_it_done = 0; + mutex->unlock(); + + return SFX_OK; +} + +static int player_fade_out(void) { + warning("Attempt to fade out - not implemented yet"); + return SFX_ERROR; +} + +static int player_stop(void) { + mutex->lock(); + delete play_it; + play_it = NULL; + mididrv->allSoundOff(); + mutex->unlock(); + + return SFX_OK; +} + +static int player_send_iterator_message(const SongIterator::Message &msg) { + mutex->lock(); + if (!play_it) { + mutex->unlock(); + return SFX_ERROR; + } + + songit_handle_message(&play_it, msg); + mutex->unlock(); + + return SFX_OK; +} + +static int player_pause(void) { + mutex->lock(); + play_paused = 1; + play_pause_diff = wakeup_time.msecsDiff(current_time); + + mididrv->allSoundOff(); + mutex->unlock(); + + return SFX_OK; +} + +static int player_resume(void) { + mutex->lock(); + wakeup_time = Audio::Timestamp(current_time.msecs() + play_pause_diff, SFX_TICKS_PER_SEC); + play_paused = 0; + mutex->unlock(); + + return SFX_OK; +} + +static int player_exit(void) { + mididrv->close(); + delete mididrv; + delete mutex; + + return SFX_OK; +} + +sfx_player_t sfx_player_player = { + "new", + "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 + diff --git a/engines/sci/sfx/player/players.cpp b/engines/sci/sfx/player/players.cpp index b07a00b036..1c9fdcea83 100644 --- a/engines/sci/sfx/player/players.cpp +++ b/engines/sci/sfx/player/players.cpp @@ -29,8 +29,10 @@ namespace Sci { extern sfx_player_t sfx_player_realtime; extern sfx_player_t sfx_player_polled; +extern sfx_player_t sfx_player_player; sfx_player_t *sfx_players[] = { +// &sfx_player_player, &sfx_player_polled, &sfx_player_realtime, NULL |