TOLTECS: Save music in saved games

Also, move all music resource related code into its own class
This commit is contained in:
Filippos Karapetis 2011-11-24 00:01:29 +02:00
parent 0565d7dc20
commit 0b4a022018
6 changed files with 75 additions and 23 deletions

View File

@ -22,9 +22,12 @@
// FIXME: This code is taken from SAGA and needs more work (e.g. setVolume). // FIXME: This code is taken from SAGA and needs more work (e.g. setVolume).
#include "toltecs/toltecs.h"
#include "toltecs/music.h" #include "toltecs/music.h"
#include "toltecs/resource.h"
#include "audio/midiparser.h" #include "audio/midiparser.h"
#include "common/textconsole.h"
namespace Toltecs { namespace Toltecs {
@ -101,4 +104,42 @@ void MusicPlayer::stopAndClear() {
_buffer = NULL; _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 } // End of namespace Made

View File

@ -26,9 +26,12 @@
#define MADE_MUSIC_H #define MADE_MUSIC_H
#include "audio/midiplayer.h" #include "audio/midiplayer.h"
#include "common/stream.h"
namespace Toltecs { namespace Toltecs {
class ArchiveReader;
class MusicPlayer : public Audio::MidiPlayer { class MusicPlayer : public Audio::MidiPlayer {
public: public:
MusicPlayer(bool isGM = true); MusicPlayer(bool isGM = true);
@ -48,6 +51,23 @@ private:
byte *_buffer; 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 #endif

View File

@ -27,6 +27,7 @@
#include "toltecs/toltecs.h" #include "toltecs/toltecs.h"
#include "toltecs/animation.h" #include "toltecs/animation.h"
#include "toltecs/music.h"
#include "toltecs/palette.h" #include "toltecs/palette.h"
#include "toltecs/script.h" #include "toltecs/script.h"
#include "toltecs/screen.h" #include "toltecs/screen.h"
@ -40,7 +41,7 @@ namespace Toltecs {
- Maybe switch to SCUMM/Tinsel serialization approach? - 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) { 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); _anim->saveState(out);
_screen->saveState(out); _screen->saveState(out);
_sound->saveState(out); _sound->saveState(out);
_music->saveState(out);
out->finalize(); out->finalize();
delete out; delete out;
@ -156,6 +158,7 @@ void ToltecsEngine::loadgame(const char *filename) {
} }
_sound->stopAll(); _sound->stopAll();
_music->stopSequence();
g_engine->setTotalPlayTime(header.playTime * 1000); g_engine->setTotalPlayTime(header.playTime * 1000);
_cameraX = in->readUint16LE(); _cameraX = in->readUint16LE();
@ -189,6 +192,8 @@ void ToltecsEngine::loadgame(const char *filename) {
_screen->loadState(in); _screen->loadState(in);
if (header.version >= 2) if (header.version >= 2)
_sound->loadState(in); _sound->loadState(in);
if (header.version >= 3)
_music->loadState(in);
delete in; delete in;

View File

@ -1009,27 +1009,13 @@ void ScriptInterpreter::sfStartSequence() {
if (sequenceResIndex >= 0) { if (sequenceResIndex >= 0) {
//_vm->_arc->dump(sequenceResIndex, "music"); // DEBUG: Dump music so we know what's in there //_vm->_arc->dump(sequenceResIndex, "music"); // DEBUG: Dump music so we know what's in there
int32 resourceSize = _vm->_arc->getResourceSize(sequenceResIndex); _vm->_music->playSequence(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;
} }
} }
void ScriptInterpreter::sfEndSequence() { void ScriptInterpreter::sfEndSequence() {
//debug("ScriptInterpreter::sfEndSequence"); //debug("ScriptInterpreter::sfEndSequence");
_vm->_musicPlayer->stopAndClear(); _vm->_music->stopSequence();
} }
void ScriptInterpreter::sfSetSequenceVolume() { void ScriptInterpreter::sfSetSequenceVolume() {

View File

@ -124,7 +124,7 @@ Common::Error ToltecsEngine::run() {
_palette = new Palette(this); _palette = new Palette(this);
_segmap = new SegmentMap(this); _segmap = new SegmentMap(this);
_moviePlayer = new MoviePlayer(this); _moviePlayer = new MoviePlayer(this);
_musicPlayer = new MusicPlayer(); _music = new Music(_arc);
_menuSystem = new MenuSystem(this); _menuSystem = new MenuSystem(this);
_sound = new Sound(this); _sound = new Sound(this);
@ -168,7 +168,7 @@ Common::Error ToltecsEngine::run() {
} }
_script->runScript(); _script->runScript();
_musicPlayer->stopAndClear(); _music->stopSequence();
_sound->stopAll(); _sound->stopAll();
delete _arc; delete _arc;
@ -178,7 +178,7 @@ Common::Error ToltecsEngine::run() {
delete _anim; delete _anim;
delete _palette; delete _palette;
delete _segmap; delete _segmap;
delete _musicPlayer; delete _music;
delete _moviePlayer; delete _moviePlayer;
delete _menuSystem; delete _menuSystem;

View File

@ -45,7 +45,7 @@ class ArchiveReader;
class Input; class Input;
class MenuSystem; class MenuSystem;
class MoviePlayer; class MoviePlayer;
class MusicPlayer; class Music;
class Palette; class Palette;
class ResourceCache; class ResourceCache;
class ScriptInterpreter; class ScriptInterpreter;
@ -134,7 +134,7 @@ public:
Input *_input; Input *_input;
MenuSystem *_menuSystem; MenuSystem *_menuSystem;
MoviePlayer *_moviePlayer; MoviePlayer *_moviePlayer;
MusicPlayer *_musicPlayer; Music *_music;
Palette *_palette; Palette *_palette;
ResourceCache *_res; ResourceCache *_res;
ScriptInterpreter *_script; ScriptInterpreter *_script;