diff --git a/engines/toltecs/music.cpp b/engines/toltecs/music.cpp index ef44421de90..c322961077d 100644 --- a/engines/toltecs/music.cpp +++ b/engines/toltecs/music.cpp @@ -22,9 +22,12 @@ // FIXME: This code is taken from SAGA and needs more work (e.g. setVolume). +#include "toltecs/toltecs.h" #include "toltecs/music.h" +#include "toltecs/resource.h" #include "audio/midiparser.h" +#include "common/textconsole.h" namespace Toltecs { @@ -101,4 +104,42 @@ void MusicPlayer::stopAndClear() { _buffer = NULL; } +Music::Music(ArchiveReader *arc) : MusicPlayer(true), _arc(arc) { + _sequenceResIndex = -1; +} + +void Music::playSequence(int16 sequenceResIndex) { + _sequenceResIndex = sequenceResIndex; + + int32 resourceSize = _arc->getResourceSize(sequenceResIndex); + byte *data = new byte[resourceSize]; + _arc->openResource(sequenceResIndex); + _arc->read(data, resourceSize); + _arc->closeResource(); + + if (!memcmp(data, "FORM", 4)) + playMIDI(data, resourceSize, true); // music tracks are always looping + else + // Sanity check: this should never occur + error("playSequence: resource %d isn't XMIDI", sequenceResIndex); + + delete[] data; +} + +void Music::stopSequence() { + _sequenceResIndex = -1; + stopAndClear(); +} + +void Music::saveState(Common::WriteStream *out) { + out->writeSint16LE(_sequenceResIndex); +} + +void Music::loadState(Common::ReadStream *in) { + _sequenceResIndex = in->readSint16LE(); + + if (_sequenceResIndex >= 0) + playSequence(_sequenceResIndex); +} + } // End of namespace Made diff --git a/engines/toltecs/music.h b/engines/toltecs/music.h index c7189e89d6a..79df1ea2f53 100644 --- a/engines/toltecs/music.h +++ b/engines/toltecs/music.h @@ -26,9 +26,12 @@ #define MADE_MUSIC_H #include "audio/midiplayer.h" +#include "common/stream.h" namespace Toltecs { +class ArchiveReader; + class MusicPlayer : public Audio::MidiPlayer { public: MusicPlayer(bool isGM = true); @@ -48,6 +51,23 @@ private: byte *_buffer; }; -} // End of namespace Made +class Music : public MusicPlayer { +public: + + Music(ArchiveReader *arc); + ~Music() {} + + void playSequence(int16 sequenceResIndex); + void stopSequence(); + + void saveState(Common::WriteStream *out); + void loadState(Common::ReadStream *in); + +private: + int16 _sequenceResIndex; + ArchiveReader *_arc; +}; + +} // End of namespace Toltecs #endif diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp index af78c8b975f..c24d2149b03 100644 --- a/engines/toltecs/saveload.cpp +++ b/engines/toltecs/saveload.cpp @@ -27,6 +27,7 @@ #include "toltecs/toltecs.h" #include "toltecs/animation.h" +#include "toltecs/music.h" #include "toltecs/palette.h" #include "toltecs/script.h" #include "toltecs/screen.h" @@ -40,7 +41,7 @@ namespace Toltecs { - Maybe switch to SCUMM/Tinsel serialization approach? */ -#define TOLTECS_SAVEGAME_VERSION 2 +#define TOLTECS_SAVEGAME_VERSION 3 ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) { @@ -133,6 +134,7 @@ void ToltecsEngine::savegame(const char *filename, const char *description) { _anim->saveState(out); _screen->saveState(out); _sound->saveState(out); + _music->saveState(out); out->finalize(); delete out; @@ -156,6 +158,7 @@ void ToltecsEngine::loadgame(const char *filename) { } _sound->stopAll(); + _music->stopSequence(); g_engine->setTotalPlayTime(header.playTime * 1000); _cameraX = in->readUint16LE(); @@ -189,6 +192,8 @@ void ToltecsEngine::loadgame(const char *filename) { _screen->loadState(in); if (header.version >= 2) _sound->loadState(in); + if (header.version >= 3) + _music->loadState(in); delete in; diff --git a/engines/toltecs/script.cpp b/engines/toltecs/script.cpp index 959db8b277d..e5fc865f5bc 100644 --- a/engines/toltecs/script.cpp +++ b/engines/toltecs/script.cpp @@ -1009,27 +1009,13 @@ void ScriptInterpreter::sfStartSequence() { if (sequenceResIndex >= 0) { //_vm->_arc->dump(sequenceResIndex, "music"); // DEBUG: Dump music so we know what's in there - int32 resourceSize = _vm->_arc->getResourceSize(sequenceResIndex); - byte *data = new byte[resourceSize]; - _vm->_arc->openResource(sequenceResIndex); - _vm->_arc->read(data, resourceSize); - _vm->_arc->closeResource(); - - if (!memcmp(data, "FORM", 4)) { - // TODO: It seems that music is always looping? - _vm->_musicPlayer->playMIDI(data, resourceSize, true); - } else { - // Sanity check: this should never occur - error("sfStartSequence: resource %d isn't XMIDI", sequenceResIndex); - } - - delete[] data; + _vm->_music->playSequence(sequenceResIndex); } } void ScriptInterpreter::sfEndSequence() { //debug("ScriptInterpreter::sfEndSequence"); - _vm->_musicPlayer->stopAndClear(); + _vm->_music->stopSequence(); } void ScriptInterpreter::sfSetSequenceVolume() { diff --git a/engines/toltecs/toltecs.cpp b/engines/toltecs/toltecs.cpp index 8a2853e4956..d403e0499b2 100644 --- a/engines/toltecs/toltecs.cpp +++ b/engines/toltecs/toltecs.cpp @@ -124,7 +124,7 @@ Common::Error ToltecsEngine::run() { _palette = new Palette(this); _segmap = new SegmentMap(this); _moviePlayer = new MoviePlayer(this); - _musicPlayer = new MusicPlayer(); + _music = new Music(_arc); _menuSystem = new MenuSystem(this); _sound = new Sound(this); @@ -168,7 +168,7 @@ Common::Error ToltecsEngine::run() { } _script->runScript(); - _musicPlayer->stopAndClear(); + _music->stopSequence(); _sound->stopAll(); delete _arc; @@ -178,7 +178,7 @@ Common::Error ToltecsEngine::run() { delete _anim; delete _palette; delete _segmap; - delete _musicPlayer; + delete _music; delete _moviePlayer; delete _menuSystem; diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h index 1334f84cb36..efa1f9d13a9 100644 --- a/engines/toltecs/toltecs.h +++ b/engines/toltecs/toltecs.h @@ -45,7 +45,7 @@ class ArchiveReader; class Input; class MenuSystem; class MoviePlayer; -class MusicPlayer; +class Music; class Palette; class ResourceCache; class ScriptInterpreter; @@ -134,7 +134,7 @@ public: Input *_input; MenuSystem *_menuSystem; MoviePlayer *_moviePlayer; - MusicPlayer *_musicPlayer; + Music *_music; Palette *_palette; ResourceCache *_res; ScriptInterpreter *_script;