From b64622744f480b04dab9603fe0c09fb76e8e25b3 Mon Sep 17 00:00:00 2001 From: Borja Lorente Date: Mon, 1 Aug 2016 12:21:35 +0200 Subject: MACVENTURE: Add infrastructure to support sound system --- engines/macventure/macventure.cpp | 82 ++++++++++++++++++++++++--------- engines/macventure/macventure.h | 21 ++++++++- engines/macventure/module.mk | 3 +- engines/macventure/script.cpp | 11 +++-- engines/macventure/sound.cpp | 95 +++++++++++++++++++++++++++++++++++++++ engines/macventure/sound.h | 85 +++++++++++++++++++++++++++++++++++ 6 files changed, 268 insertions(+), 29 deletions(-) create mode 100644 engines/macventure/sound.cpp create mode 100644 engines/macventure/sound.h (limited to 'engines') diff --git a/engines/macventure/macventure.cpp b/engines/macventure/macventure.cpp index 9cba0502ce..5d9d6f9938 100644 --- a/engines/macventure/macventure.cpp +++ b/engines/macventure/macventure.cpp @@ -54,6 +54,8 @@ MacVentureEngine::MacVentureEngine(OSystem *syst, const ADGameDescription *gameD _debugger = NULL; _gui = NULL; + _soundManager = NULL; + debug("MacVenture::MacVentureEngine()"); } @@ -80,6 +82,9 @@ MacVentureEngine::~MacVentureEngine() { if (_textHuffman) delete _textHuffman; + + if (_soundManager) + delete _soundManager; } Common::Error MacVentureEngine::run() { @@ -112,6 +117,8 @@ Common::Error MacVentureEngine::run() { _world = new World(this, _resourceManager); _scriptEngine = new ScriptEngine(this, _world); + _soundManager = new SoundManager(this); + _paused = false; _halted = false; _cmdReady = false; @@ -314,26 +321,11 @@ void MacVentureEngine::enqueueText(TextQueueID type, ObjID target, ObjID source, _textQueue.push_back(newText); } -bool MacVentureEngine::printTexts() { - for (uint i = 0; i < _textQueue.size(); i++) { - QueuedText text = _textQueue.front(); - _textQueue.remove_at(0); - switch (text.id) { - case kTextNumber: - _gui->printText(Common::String(text.asset)); - gameChanged(); - break; - case kTextNewLine: - _gui->printText(Common::String("")); - gameChanged(); - break; - case kTextPlain: - _gui->printText(_world->getText(text.asset, text.source, text.destination)); - gameChanged(); - break; - } - } - return false; +void MacVentureEngine::enqueueSound(SoundQueueID type, ObjID target) { + QueuedSound newSound; + newSound.id = type; + newSound.reference = target; + _soundQueue.push_back(newSound); } void MacVentureEngine::handleObjectSelect(ObjID objID, WindowReference win, bool shiftPressed, bool isDoubleClick) { @@ -529,6 +521,8 @@ void MacVentureEngine::endGame() { bool MacVentureEngine::updateState() { runObjQueue(); bool wait = printTexts(); + // HACK playSounds should accept a bool passed to updateState + wait |= playSounds(true); return wait; } @@ -581,6 +575,54 @@ void MacVentureEngine::runObjQueue() { } } +bool MacVentureEngine::printTexts() { + for (uint i = 0; i < _textQueue.size(); i++) { + QueuedText text = _textQueue.front(); + _textQueue.remove_at(0); + switch (text.id) { + case kTextNumber: + _gui->printText(Common::String(text.asset)); + gameChanged(); + break; + case kTextNewLine: + _gui->printText(Common::String("")); + gameChanged(); + break; + case kTextPlain: + _gui->printText(_world->getText(text.asset, text.source, text.destination)); + gameChanged(); + break; + } + } + return false; +} + +bool MacVentureEngine::playSounds(bool pause) { + int delay=0; + while (!_soundQueue.empty()) { + QueuedSound item = _soundQueue.front(); + _soundQueue.remove_at(0); + switch (item.id) { + case kSoundPlay: + _soundManager->playSound(item.reference); + break; + case kSoundPlayAndWait: + delay = _soundManager->playSound(item.reference); + break; + case kSoundWait: + //wait for sound to finish? + break; + } + } + if (pause && delay > 0) { + warning("Sound pausing not yet tested. Pausing for %d", delay * 1000); + g_system->delayMillis(delay * 1000); + preparedToRun(); + return true; + } + return false; +} + void MacVentureEngine::updateControls() { if (_activeControl) _activeControl = kNoCommand; diff --git a/engines/macventure/macventure.h b/engines/macventure/macventure.h index 6baaa31ac1..28eb8e42ff 100644 --- a/engines/macventure/macventure.h +++ b/engines/macventure/macventure.h @@ -41,6 +41,7 @@ #include "macventure/script.h" #include "macventure/controls.h" #include "macventure/windows.h" +#include "macventure/sound.h" struct ADGameDescription; @@ -52,6 +53,8 @@ class Console; class World; class ScriptEngine; +class SoundManager; + typedef uint32 ObjID; // HACK, until I find a way to translate correctly @@ -161,6 +164,17 @@ struct QueuedText { ObjID asset; }; +enum SoundQueueID { + kSoundPlay = 1, + kSoundPlayAndWait = 2, + kSoundWait = 3 +}; + +struct QueuedSound { + SoundQueueID id; + ObjID reference; +}; + class MacVentureEngine : public Engine { public: @@ -191,9 +205,11 @@ public: void enqueueObject(ObjectQueueID type, ObjID objID, ObjID target = 0); void enqueueText(TextQueueID type, ObjID target, ObjID source, ObjID text); + void enqueueSound(SoundQueueID type, ObjID target); void runObjQueue(); bool printTexts(); + bool playSounds(bool pause); void handleObjectSelect(ObjID objID, WindowReference win, bool shiftPressed, bool isDoubleClick); void handleObjectDrop(ObjID objID, Common::Point delta, ObjID newParent); @@ -205,7 +221,6 @@ public: void setTextInput(Common::String content); Common::String getUserInput(); - // Data retrieval Common::String getStartGameFileName(); bool isPaused(); @@ -296,6 +311,8 @@ private: // Attributes StringTable *_decodingNamingArticles; StringTable *_decodingIndirectArticles; + SoundManager *_soundManager; + // Engine state GameState _gameState; GlobalSettings _globalSettings; @@ -308,7 +325,7 @@ private: // Attributes Common::Array _objQueue; Common::Array _inQueue; - Common::Array _soundQueue; + Common::Array _soundQueue; Common::Array _textQueue; // Selections diff --git a/engines/macventure/module.mk b/engines/macventure/module.mk index 48c8930520..a1e2f5ef71 100644 --- a/engines/macventure/module.mk +++ b/engines/macventure/module.mk @@ -12,7 +12,8 @@ MODULE_OBJS := \ dialog.o \ controls.o \ prebuilt_dialogs.o \ - windows.o + windows.o \ + sound.o MODULE_DIRS += \ diff --git a/engines/macventure/script.cpp b/engines/macventure/script.cpp index 51bfa3382b..55bb4063bd 100644 --- a/engines/macventure/script.cpp +++ b/engines/macventure/script.cpp @@ -32,7 +32,6 @@ namespace MacVenture { ScriptEngine::ScriptEngine(MacVentureEngine * engine, World * world) { _engine = engine; _world = world; - // HACK _scripts = new Container(_engine->getFilePath(kFilterPathID)); } @@ -989,17 +988,17 @@ void ScriptEngine::opc6P2(EngineState * state, EngineFrame * frame) { } void ScriptEngine::opc7PLBG(EngineState * state, EngineFrame * frame) { - state->pop(); - op00NOOP(0xc7); + word target = state->pop(); + _engine->enqueueSound(kSoundPlay, target); } void ScriptEngine::opc8PLAW(EngineState * state, EngineFrame * frame) { - state->pop(); - op00NOOP(0xc8); + word target = state->pop(); + _engine->enqueueSound(kSoundPlayAndWait, target); } void ScriptEngine::opc9WAIT(EngineState * state, EngineFrame * frame) { - op00NOOP(0xc9); + _engine->enqueueSound(kSoundWait, 0); } void ScriptEngine::opcaTIME(EngineState * state, EngineFrame * frame) { diff --git a/engines/macventure/sound.cpp b/engines/macventure/sound.cpp new file mode 100644 index 0000000000..2addb1932b --- /dev/null +++ b/engines/macventure/sound.cpp @@ -0,0 +1,95 @@ +/* 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 "macventure/sound.h" + +namespace MacVenture { + +SoundAsset::SoundAsset(Container *container, ObjID id) : + _container(container), _id(id) { + + //TODO Decode the sound + if (_container->getItemByteSize(_id) == 0) + warning("Trying to load an empty sound asset."); + + Common::SeekableReadStream *stream = _container->getItem(_id); + + stream->seek(5, SEEK_SET); + SoundType type = (SoundType)stream->readByte(); + + switch(type) { + case kSound10: + decode10(stream); + break; + default: + warning("Unrecognized sound type: %x", type); + } + + delete stream; +} + +SoundAsset::~SoundAsset() {} + +void SoundAsset::play() { + //TODO: Play song + warning("SoundAsset::play() not yet implemented"); +} + +uint32 SoundAsset::getPlayLength() { + return _length / _frequency; +} + +void SoundAsset::decode10(Common::SeekableReadStream *stream) { + //TODO: Decode 10 + debug("Decoding sound type 10"); +} + +// SoundManager +SoundManager::SoundManager(MacVentureEngine *engine) { + _container = nullptr; + Common::String filename = engine->getFilePath(kSoundPathID); + _container = new Container(filename); + debug("Created sound manager with file %s", filename.c_str()); +} + +SoundManager::~SoundManager(){ + if (_container) + delete _container; + + Common::HashMap::iterator it; + for (it = _assets.begin(); it != _assets.end(); it++) { + delete it->_value; + } +} + +uint32 SoundManager::playSound(ObjID sound) { + ensureLoaded(sound); + _assets[sound]->play(); + return _assets[sound]->getPlayLength(); +} + +void SoundManager::ensureLoaded(ObjID sound) { + if (!_assets.contains(sound)) + _assets[sound] = new SoundAsset(_container, sound); +} + +} //End of namespace MacVenture diff --git a/engines/macventure/sound.h b/engines/macventure/sound.h new file mode 100644 index 0000000000..3c7a68fc2b --- /dev/null +++ b/engines/macventure/sound.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. +* +*/ + +#ifndef MACVENTURE_SOUND_H +#define MACVENTURE_SOUND_H + +#include "macventure/macventure.h" +#include "macventure/container.h" + +#include "common/file.h" +#include "common/hashmap.h" + +namespace MacVenture { + +enum SoundType { + kSound10 = 0x10, + kSound12 = 0x12, + kSound18 = 0x18, + kSound1a = 0x1a, + kSound44 = 0x44, + kSound78 = 0x78, + kSound7e = 0x7e +}; + +class SoundAsset { + +public: + SoundAsset(Container *container, ObjID id); + ~SoundAsset(); + + void play(); + uint32 getPlayLength(); + +private: + + void decode10(Common::SeekableReadStream *stream); + +private: + + Container *_container; + ObjID _id; + + Common::Array _data; + uint32 _length; + uint32 _frequency; +}; + +class SoundManager { +public: + SoundManager(MacVentureEngine *engine); + ~SoundManager(); + + uint32 playSound(ObjID sound); + +private: + void ensureLoaded(ObjID sound); + +private: + + Container *_container; + Common::HashMap _assets; + +}; +} // End of namespace MacVenture + +#endif -- cgit v1.2.3