From 5d3385750ddf68f5347bf51f005c86a8e70283e2 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Thu, 9 Jun 2016 20:50:56 -0500 Subject: SCI: Split audio sync to its own class SCI32 has its own audio handling code, but audio sync code is the same as SCI16. --- engines/sci/engine/ksound.cpp | 11 +++---- engines/sci/module.mk | 1 + engines/sci/sci.cpp | 5 +++ engines/sci/sci.h | 2 ++ engines/sci/sound/audio.cpp | 41 +---------------------- engines/sci/sound/audio.h | 12 ------- engines/sci/sound/sync.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++ engines/sci/sound/sync.h | 57 ++++++++++++++++++++++++++++++++ 8 files changed, 146 insertions(+), 58 deletions(-) create mode 100644 engines/sci/sound/sync.cpp create mode 100644 engines/sci/sound/sync.h (limited to 'engines') diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index 398a623286..2b22d6867b 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -27,6 +27,7 @@ #include "sci/engine/vm.h" // for Object #include "sci/sound/audio.h" #include "sci/sound/soundcmd.h" +#include "sci/sound/sync.h" #include "audio/mixer.h" #include "common/system.h" @@ -286,14 +287,12 @@ reg_t kDoAudio(EngineState *s, int argc, reg_t *argv) { } reg_t kDoSync(EngineState *s, int argc, reg_t *argv) { - SegManager *segMan = s->_segMan; switch (argv[0].toUint16()) { case kSciAudioSyncStart: { ResourceId id; - g_sci->_audio->stopSoundSync(); + g_sci->_sync->stop(); - // Load sound sync resource and lock it if (argc == 3) { id = ResourceId(kResourceTypeSync, argv[2].toUint16()); } else if (argc == 7) { @@ -304,14 +303,14 @@ reg_t kDoSync(EngineState *s, int argc, reg_t *argv) { return s->r_acc; } - g_sci->_audio->setSoundSync(id, argv[1], segMan); + g_sci->_sync->start(id, argv[1]); break; } case kSciAudioSyncNext: - g_sci->_audio->doSoundSync(argv[1], segMan); + g_sci->_sync->next(argv[1]); break; case kSciAudioSyncStop: - g_sci->_audio->stopSoundSync(); + g_sci->_sync->stop(); break; default: error("DoSync: Unhandled subfunction %d", argv[0].toUint16()); diff --git a/engines/sci/module.mk b/engines/sci/module.mk index a02147e4d0..c35d0b51dd 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -69,6 +69,7 @@ MODULE_OBJS := \ sound/midiparser_sci.o \ sound/music.o \ sound/soundcmd.o \ + sound/sync.o \ sound/drivers/adlib.o \ sound/drivers/amigamac.o \ sound/drivers/cms.o \ diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index e14d12b918..8c23d322e7 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -43,6 +43,7 @@ #include "sci/sound/audio.h" #include "sci/sound/music.h" +#include "sci/sound/sync.h" #include "sci/sound/soundcmd.h" #include "sci/graphics/animate.h" #include "sci/graphics/cache.h" @@ -86,6 +87,7 @@ SciEngine::SciEngine(OSystem *syst, const ADGameDescription *desc, SciGameId gam _gfxMacIconBar = 0; _audio = 0; + _sync = nullptr; _features = 0; _resMan = 0; _gamestate = 0; @@ -182,6 +184,7 @@ SciEngine::~SciEngine() { delete _gfxScreen; delete _audio; + delete _sync; delete _soundCmd; delete _kernel; delete _vocabulary; @@ -267,6 +270,7 @@ Common::Error SciEngine::run() { if (getGameId() == GID_CHRISTMAS1990) _vocabulary = new Vocabulary(_resMan, false); _audio = new AudioPlayer(_resMan); + _sync = new Sync(_resMan, segMan); _gamestate = new EngineState(segMan); _eventMan = new EventManager(_resMan->detectFontExtended()); @@ -802,6 +806,7 @@ void SciEngine::exitGame() { if (_gamestate->abortScriptProcessing != kAbortLoadGame) { _gamestate->_executionStack.clear(); _audio->stopAllAudio(); + _sync->stop(); _soundCmd->clearPlayList(); } diff --git a/engines/sci/sci.h b/engines/sci/sci.h index c49a516d01..ff414727fa 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -56,6 +56,7 @@ class SoundCommandParser; class EventManager; class SegManager; class ScriptPatcher; +class Sync; class GfxAnimate; class GfxCache; @@ -372,6 +373,7 @@ public: #endif AudioPlayer *_audio; + Sync *_sync; SoundCommandParser *_soundCmd; GameFeatures *_features; diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp index a74bfa245f..71b081049e 100644 --- a/engines/sci/sound/audio.cpp +++ b/engines/sci/sound/audio.cpp @@ -22,7 +22,6 @@ #include "sci/resource.h" #include "sci/engine/kernel.h" -#include "sci/engine/selector.h" #include "sci/engine/seg_manager.h" #include "sci/sound/audio.h" @@ -45,7 +44,7 @@ namespace Sci { AudioPlayer::AudioPlayer(ResourceManager *resMan) : _resMan(resMan), _audioRate(11025), - _syncResource(NULL), _syncOffset(0), _audioCdStart(0), _initCD(false) { + _audioCdStart(0), _initCD(false) { _mixer = g_system->getMixer(); _wPlayFlag = false; @@ -56,7 +55,6 @@ AudioPlayer::~AudioPlayer() { } void AudioPlayer::stopAllAudio() { - stopSoundSync(); stopAudio(); if (_audioCdStart > 0) audioCdStop(); @@ -474,43 +472,6 @@ Audio::RewindableAudioStream *AudioPlayer::getAudioStream(uint32 number, uint32 return NULL; } -void AudioPlayer::setSoundSync(ResourceId id, reg_t syncObjAddr, SegManager *segMan) { - _syncResource = _resMan->findResource(id, 1); - _syncOffset = 0; - - if (_syncResource) { - writeSelectorValue(segMan, syncObjAddr, SELECTOR(syncCue), 0); - } else { - warning("setSoundSync: failed to find resource %s", id.toString().c_str()); - // Notify the scripts to stop sound sync - writeSelectorValue(segMan, syncObjAddr, SELECTOR(syncCue), SIGNAL_OFFSET); - } -} - -void AudioPlayer::doSoundSync(reg_t syncObjAddr, SegManager *segMan) { - if (_syncResource && (_syncOffset < _syncResource->size - 1)) { - int16 syncCue = -1; - int16 syncTime = (int16)READ_SCI11ENDIAN_UINT16(_syncResource->data + _syncOffset); - - _syncOffset += 2; - - if ((syncTime != -1) && (_syncOffset < _syncResource->size - 1)) { - syncCue = (int16)READ_SCI11ENDIAN_UINT16(_syncResource->data + _syncOffset); - _syncOffset += 2; - } - - writeSelectorValue(segMan, syncObjAddr, SELECTOR(syncTime), syncTime); - writeSelectorValue(segMan, syncObjAddr, SELECTOR(syncCue), syncCue); - } -} - -void AudioPlayer::stopSoundSync() { - if (_syncResource) { - _resMan->unlockResource(_syncResource); - _syncResource = NULL; - } -} - int AudioPlayer::audioCdPlay(int track, int start, int duration) { if (!_initCD) { // Initialize CD mode if we haven't already diff --git a/engines/sci/sound/audio.h b/engines/sci/sound/audio.h index 4a8b26567d..3d25dcaeef 100644 --- a/engines/sci/sound/audio.h +++ b/engines/sci/sound/audio.h @@ -46,12 +46,6 @@ enum AudioCommands { kSciAudioCD = 10 /* Plays SCI1.1 CD audio */ }; -enum AudioSyncCommands { - kSciAudioSyncStart = 0, - kSciAudioSyncNext = 1, - kSciAudioSyncStop = 2 -}; - #define AUDIO_VOLUME_MAX 127 class Resource; @@ -77,10 +71,6 @@ public: void handleFanmadeSciAudio(reg_t sciAudioObject, SegManager *segMan); - void setSoundSync(ResourceId id, reg_t syncObjAddr, SegManager *segMan); - void doSoundSync(reg_t syncObjAddr, SegManager *segMan); - void stopSoundSync(); - int audioCdPlay(int track, int start, int duration); void audioCdStop(); void audioCdUpdate(); @@ -93,8 +83,6 @@ private: uint16 _audioRate; Audio::SoundHandle _audioHandle; Audio::Mixer *_mixer; - Resource *_syncResource; /**< Used by kDoSync for speech syncing in CD talkie games */ - uint _syncOffset; uint32 _audioCdStart; bool _wPlayFlag; bool _initCD; diff --git a/engines/sci/sound/sync.cpp b/engines/sci/sound/sync.cpp new file mode 100644 index 0000000000..08abad188b --- /dev/null +++ b/engines/sci/sound/sync.cpp @@ -0,0 +1,75 @@ +/* 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. + * + */ + +#include "sci/engine/kernel.h" +#include "sci/util.h" +#include "sync.h" + +namespace Sci { +Sync::Sync(ResourceManager *resMan, SegManager *segMan) : + _resMan(resMan), + _segMan(segMan), + _resource(nullptr), + _offset(0) {} + +Sync::~Sync() { + stop(); +} + +void Sync::start(const ResourceId id, const reg_t syncObjAddr) { + _resource = _resMan->findResource(id, true); + _offset = 0; + + if (_resource) { + writeSelectorValue(_segMan, syncObjAddr, SELECTOR(syncCue), 0); + } else { + warning("Sync::start: failed to find resource %s", id.toString().c_str()); + // Notify the scripts to stop sound sync + writeSelectorValue(_segMan, syncObjAddr, SELECTOR(syncCue), SIGNAL_OFFSET); + } +} + +void Sync::next(const reg_t syncObjAddr) { + if (_resource && (_offset < _resource->size - 1)) { + int16 syncCue = -1; + int16 syncTime = (int16)READ_SCI11ENDIAN_UINT16(_resource->data + _offset); + + _offset += 2; + + if ((syncTime != -1) && (_offset < _resource->size - 1)) { + syncCue = (int16)READ_SCI11ENDIAN_UINT16(_resource->data + _offset); + _offset += 2; + } + + writeSelectorValue(_segMan, syncObjAddr, SELECTOR(syncTime), syncTime); + writeSelectorValue(_segMan, syncObjAddr, SELECTOR(syncCue), syncCue); + } +} + +void Sync::stop() { + if (_resource) { + _resMan->unlockResource(_resource); + _resource = nullptr; + } +} + +} // End of namespace Sci diff --git a/engines/sci/sound/sync.h b/engines/sci/sound/sync.h new file mode 100644 index 0000000000..c80982bff7 --- /dev/null +++ b/engines/sci/sound/sync.h @@ -0,0 +1,57 @@ +/* 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. + * + */ + +#ifndef SCI_SOUND_SYNC_H +#define SCI_SOUND_SYNC_H + +#include "sci/engine/selector.h" +#include "sci/engine/vm_types.h" + +namespace Sci { + +enum AudioSyncCommands { + kSciAudioSyncStart = 0, + kSciAudioSyncNext = 1, + kSciAudioSyncStop = 2 +}; + +class Resource; +class ResourceManager; +class SegManager; + +class Sync { + SegManager *_segMan; + ResourceManager *_resMan; + Resource *_resource; + uint _offset; + +public: + Sync(ResourceManager *resMan, SegManager *segMan); + ~Sync(); + + void start(const ResourceId id, const reg_t syncObjAddr); + void next(const reg_t syncObjAddr); + void stop(); +}; + +} +#endif -- cgit v1.2.3