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).
#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

View File

@ -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

View File

@ -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;

View File

@ -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() {

View File

@ -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;

View File

@ -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;