diff options
Diffstat (limited to 'engines/composer')
-rw-r--r-- | engines/composer/graphics.cpp | 3 | ||||
-rw-r--r-- | engines/composer/graphics.h | 3 | ||||
-rw-r--r-- | engines/composer/resource.cpp | 2 | ||||
-rw-r--r-- | engines/composer/saveload.cpp | 226 |
4 files changed, 176 insertions, 58 deletions
diff --git a/engines/composer/graphics.cpp b/engines/composer/graphics.cpp index b69e09d9bf..2c50cb11e7 100644 --- a/engines/composer/graphics.cpp +++ b/engines/composer/graphics.cpp @@ -57,6 +57,9 @@ Animation::Animation(Common::SeekableReadStream *stream, uint16 id, Common::Poin // probably total size? uint32 unknown = _stream->readUint32LE(); +#ifdef SAVING_ANYWHERE + _size = unknown; +#endif debug(8, "anim: size %d, state %08x, unknown %08x", size, _state, unknown); diff --git a/engines/composer/graphics.h b/engines/composer/graphics.h index a8f37ddf60..cfa581d75f 100644 --- a/engines/composer/graphics.h +++ b/engines/composer/graphics.h @@ -59,6 +59,9 @@ struct Animation { uint32 _eventParam; uint32 _state; +#ifdef SAVING_ANYWHERE + uint32 _size; +#endif Common::Array<AnimationEntry> _entries; diff --git a/engines/composer/resource.cpp b/engines/composer/resource.cpp index 3e787cc766..0bb7e8a779 100644 --- a/engines/composer/resource.cpp +++ b/engines/composer/resource.cpp @@ -252,7 +252,9 @@ Pipe::Pipe(Common::SeekableReadStream *stream, uint16 pipeId) { _offset = 0; _stream = stream; _anim = NULL; +#ifdef SAVING_ANYWHERE _pipeId = pipeId; +#endif } Pipe::~Pipe() { diff --git a/engines/composer/saveload.cpp b/engines/composer/saveload.cpp index ce0a60b04b..0cbf749f92 100644 --- a/engines/composer/saveload.cpp +++ b/engines/composer/saveload.cpp @@ -21,6 +21,8 @@ */ #ifdef SAVING_ANYWHERE +#include "audio/audiostream.h" +#include "audio/decoders/raw.h" #include "common/config-manager.h" #include "common/memstream.h" #include "common/savefile.h" @@ -49,11 +51,6 @@ Common::Error ComposerEngine::loadGameState(int slot) { if (magic[0] != 'C' || magic[1] != 'M' || magic[2] != 'P' || magic[3] != 'S') return Common::kUnknownError; - for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) { - delete *i; - } - _anims.clear(); - ser.syncVersion(0); Common::String desc; ser.syncString(desc); @@ -66,36 +63,17 @@ Common::Error ComposerEngine::loadGameState(int slot) { ser.syncAsUint32LE(_lastTime); _lastTime += timeDelta; ser.syncString(_bookGroup); - _libraries.clear(); + Common::Array<uint16> libIds; + for (Common::List<Library>::iterator i = _libraries.begin(); i != _libraries.end(); i++) + libIds.push_back((*i)._id); + for (uint32 i = 0; i < libIds.size(); i++) + unloadLibrary(libIds[i]); ser.syncAsUint32LE(tmp); for (uint32 i = tmp; i > 0; i--) { uint16 id; ser.syncAsUint16LE(id); loadLibrary(id); } - _sprites.clear(); - ser.syncAsUint32LE(tmp); - for (uint32 i = tmp; i > 0; i--) { - uint16 id; - ser.syncAsUint16LE(id); - Sprite sprite; - sprite._id = id; - ser.syncAsSint16LE(sprite._pos.x); - ser.syncAsSint16LE(sprite._pos.y); - ser.syncAsUint16LE(sprite._surface.w); - ser.syncAsUint16LE(sprite._surface.h); - ser.syncAsUint16LE(sprite._surface.pitch); - ser.syncAsUint16LE(sprite._zorder); - sprite._surface.pixels = malloc(sprite._surface.h * sprite._surface.pitch); - byte *dest = static_cast<byte *>(sprite._surface.pixels); - for (uint16 y = 0; y < sprite._surface.h; y++) { - for (uint16 x = 0; x < sprite._surface.w; x++) { - ser.syncAsByte(dest[x]); - } - dest += sprite._surface.pitch; - } - _sprites.push_back(sprite); - } _pendingPageChanges.clear(); ser.syncAsUint32LE(tmp); @@ -177,6 +155,94 @@ Common::Error ComposerEngine::loadGameState(int slot) { _pipeStreams.push_back(stream); } + for (Common::List<Animation *>::iterator i = _anims.begin(); i != _anims.end(); i++) { + delete *i; + } + _anims.clear(); + ser.syncAsUint32LE(tmp); + for (uint32 i = tmp; i > 0; i--) { + uint16 animId, x, y; + uint32 offset, state, param, size; + ser.syncAsUint16LE(animId); + ser.syncAsUint32LE(offset); + ser.syncAsUint16LE(x); + ser.syncAsUint16LE(y); + ser.syncAsUint32LE(state); + ser.syncAsUint32LE(param); + ser.syncAsUint32LE(size); + Common::SeekableReadStream *stream = NULL; + + //TODO: extract following out into "loadAnim" + // First, check the existing pipes. + for (Common::List<Pipe *>::iterator j = _pipes.begin(); j != _pipes.end(); j++) { + Pipe *pipe = *j; + if (!pipe->hasResource(ID_ANIM, animId)) + continue; + stream = pipe->getResource(ID_ANIM, animId, false); + if (stream->size() >= size) break; + stream = NULL; + } + // If we didn't find it, try the libraries. + if (!stream) { + Common::List<Library>::iterator i; + for (i = _libraries.begin(); i != _libraries.end(); i++) { + if (!hasResource(ID_ANIM, animId)) continue; + stream = getResource(ID_ANIM, animId); + if (stream->size() >= size) break; + stream = NULL; + } + if (!stream) { + warning("ignoring attempt to play invalid anim %d", animId); + continue; + } + + uint32 type = i->_archive->getResourceFlags(ID_ANIM, animId); + + // If the resource is a pipe itself, then load the pipe + // and then fish the requested animation out of it. + if (type != 1) { + _pipeStreams.push_back(stream); + Pipe *newPipe = new Pipe(stream, animId); + _pipes.push_front(newPipe); + newPipe->nextFrame(); + stream = newPipe->getResource(ID_ANIM, animId, false); + } + } + + Animation *anim = new Animation(stream, animId, Common::Point(x, y), param); + anim->_offset = offset; + anim->_state = state; + uint32 tmp2; + ser.syncAsUint32LE(tmp2); + for (uint32 j = 0; j < tmp2; j++) { + ser.syncAsUint32LE(anim->_entries[j].state); + ser.syncAsUint16LE(anim->_entries[j].counter); + ser.syncAsUint16LE(anim->_entries[j].prevValue); + } + _anims.push_back(anim); + } + _sprites.clear(); + ser.syncAsUint32LE(tmp); + for (uint32 i = tmp; i > 0; i--) { + Sprite sprite; + ser.syncAsUint16LE(sprite._id); + ser.syncAsUint16LE(sprite._animId); + ser.syncAsSint16LE(sprite._pos.x); + ser.syncAsSint16LE(sprite._pos.y); + ser.syncAsUint16LE(sprite._surface.w); + ser.syncAsUint16LE(sprite._surface.h); + ser.syncAsUint16LE(sprite._surface.pitch); + ser.syncAsUint16LE(sprite._zorder); + sprite._surface.pixels = malloc(sprite._surface.h * sprite._surface.pitch); + byte *dest = static_cast<byte *>(sprite._surface.pixels); + for (uint16 y = 0; y < sprite._surface.h; y++) { + for (uint16 x = 0; x < sprite._surface.w; x++) { + ser.syncAsByte(dest[x]); + } + dest += sprite._surface.pitch; + } + _sprites.push_back(sprite); + } _dirtyRects.clear(); _dirtyRects.push_back(Common::Rect(0, 0, 640, 480)); byte palbuf[256 * 3]; @@ -184,6 +250,17 @@ Common::Error ComposerEngine::loadGameState(int slot) { _system->getPaletteManager()->setPalette(palbuf, 0, 256); _needsUpdate = true; + _mixer->stopAll(); + _audioStream = NULL; + ser.syncAsUint32LE(tmp); + tmp <<= 1; + byte *audioBuf = (byte *)malloc(tmp); + ser.syncBytes(audioBuf, tmp); + _audioStream = Audio::makeQueuingAudioStream(22050, false); + _audioStream->queueBuffer(audioBuf, tmp, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED); + _currSoundPriority = 0; + if (!_mixer->isSoundHandleActive(_soundHandle)) + _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _audioStream); return Common::kNoError; } @@ -207,27 +284,8 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc tmp = _libraries.size(); ser.syncAsUint32LE(tmp); for (Common::List<Library>::const_iterator i = _libraries.reverse_begin(); i != _libraries.end(); i--) { - uint16 tmp = (*i)._id; - ser.syncAsUint16LE(tmp); - } - tmp = _sprites.size(); - ser.syncAsUint32LE(tmp); - for (Common::List<Sprite>::const_iterator i = _sprites.begin(); i != _sprites.end(); i++) { - Sprite sprite(*i); - ser.syncAsUint16LE(sprite._id); - ser.syncAsSint16LE(sprite._pos.x); - ser.syncAsSint16LE(sprite._pos.y); - ser.syncAsUint16LE(sprite._surface.w); - ser.syncAsUint16LE(sprite._surface.h); - ser.syncAsUint16LE(sprite._surface.pitch); - ser.syncAsUint16LE(sprite._zorder); - byte *src = static_cast<byte *>((*i)._surface.pixels); - for (uint16 y = 0; y < sprite._surface.h; y++) { - for (uint x = 0; x < sprite._surface.w; x++) { - ser.syncAsByte(src[x]); - } - src += (*i)._surface.pitch; - } + uint16 tmp16 = (*i)._id; + ser.syncAsUint16LE(tmp16); } tmp = _pendingPageChanges.size(); ser.syncAsUint32LE(tmp); @@ -240,14 +298,14 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc tmp = _stack.size(); ser.syncAsUint32LE(tmp); for (Common::Array<uint16>::const_iterator i = _stack.begin(); i != _stack.end(); i++) { - uint16 tmp = (*i); - ser.syncAsUint16LE(tmp); + uint16 tmp16 = (*i); + ser.syncAsUint16LE(tmp16); } tmp = _vars.size(); ser.syncAsUint32LE(tmp); for (Common::Array<uint16>::const_iterator i = _vars.begin(); i != _vars.end(); i++) { - uint16 tmp = (*i); - ser.syncAsUint16LE(tmp); + uint16 tmp16 = (*i); + ser.syncAsUint16LE(tmp16); } tmp = _oldScripts.size(); ser.syncAsUint32LE(tmp); @@ -287,10 +345,62 @@ Common::Error ComposerEngine::saveGameState(int slot, const Common::String &desc ser.syncAsUint32LE(tmp); } - byte palbuf[256 * 3]; - _system->getPaletteManager()->grabPalette(palbuf, 0, 256); - ser.syncBytes(palbuf, 256 * 3); - + tmp = _anims.size(); + ser.syncAsUint32LE(tmp); + for (Common::List<Animation *>::const_iterator i = _anims.begin(); i != _anims.end(); i++) { + uint16 tmp16 = (*i)->_id; + tmp = (*i)->_offset; + ser.syncAsUint16LE(tmp16); + ser.syncAsUint32LE(tmp); + tmp16 = (*i)->_basePos.x; + ser.syncAsUint16LE(tmp16); + tmp16 = (*i)->_basePos.y; + ser.syncAsUint16LE(tmp16); + tmp = (*i)->_state; + ser.syncAsUint32LE(tmp); + tmp = (*i)->_eventParam; + ser.syncAsUint32LE(tmp); + tmp = (*i)->_size; + ser.syncAsUint32LE(tmp); + tmp = (*i)->_entries.size(); + ser.syncAsUint32LE(tmp); + for (Common::Array<AnimationEntry>::const_iterator j = (*i)->_entries.begin(); j != (*i)->_entries.end(); j++) { + tmp = (*j).state; + tmp16 = (*j).counter; + ser.syncAsUint32LE(tmp); + ser.syncAsUint16LE(tmp16); + tmp16 = (*j).prevValue; + ser.syncAsUint16LE(tmp16); + } + } + tmp = _sprites.size(); + ser.syncAsUint32LE(tmp); + for (Common::List<Sprite>::const_iterator i = _sprites.begin(); i != _sprites.end(); i++) { + Sprite sprite(*i); + ser.syncAsUint16LE(sprite._id); + ser.syncAsUint16LE(sprite._animId); + ser.syncAsSint16LE(sprite._pos.x); + ser.syncAsSint16LE(sprite._pos.y); + ser.syncAsUint16LE(sprite._surface.w); + ser.syncAsUint16LE(sprite._surface.h); + ser.syncAsUint16LE(sprite._surface.pitch); + ser.syncAsUint16LE(sprite._zorder); + byte *src = static_cast<byte *>((*i)._surface.pixels); + for (uint16 y = 0; y < sprite._surface.h; y++) { + for (uint x = 0; x < sprite._surface.w; x++) { + ser.syncAsByte(src[x]); + } + src += (*i)._surface.pitch; + } + } + byte paletteBuffer[256 * 3]; + _system->getPaletteManager()->grabPalette(paletteBuffer, 0, 256); + ser.syncBytes(paletteBuffer, 256 * 3); + byte *audioBuffer = (byte *)malloc(22050 * 60 * 2); + int32 numSamples = _audioStream->readBuffer((int16 *)audioBuffer, 22050 * 60); + if (numSamples == -1) numSamples = 0; + ser.syncAsUint32LE(numSamples); + ser.syncBytes((byte *)audioBuffer, numSamples * 2); out->finalize(); return Common::kNoError; } |