mirror of
https://github.com/scummvm/scummvm.git
synced 2026-05-21 05:40:43 +00:00
- Committed Max' compressed save backseeking support from patch #2050337 "KYRA/SCUMM: Thumbnail support/improvement"
- Extended SCUMM engine to support savegames without thumbnail header. (Increased savegame version to prevent saves to be loaded from older ScummVM versions) - Fixed KYRA to properly support savegames without thumbnail header. svn-id: r34054
This commit is contained in:
@@ -62,7 +62,7 @@ public:
|
||||
_stream.zfree = Z_NULL;
|
||||
_stream.opaque = Z_NULL;
|
||||
|
||||
// Verify file header is correct once more
|
||||
// Verify file header is correct
|
||||
w->seek(0, SEEK_SET);
|
||||
uint16 header = w->readUint16BE();
|
||||
assert(header == 0x1F8B ||
|
||||
@@ -133,28 +133,35 @@ public:
|
||||
}
|
||||
void seek(int32 offset, int whence = SEEK_SET) {
|
||||
int32 newPos = 0;
|
||||
assert(whence != SEEK_END); // SEEK_END not supported
|
||||
switch(whence) {
|
||||
case SEEK_END:
|
||||
newPos = size() - offset;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
newPos = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
newPos = _pos + offset;
|
||||
}
|
||||
|
||||
assert(newPos >= 0);
|
||||
|
||||
if ((uint32)newPos < _pos) {
|
||||
// To search backward, we have to restart the whole decompression
|
||||
// from the start of the file. A rather wasteful operation, best
|
||||
// to avoid it. :/
|
||||
#if DEBUG
|
||||
warning("Backward seeking in CompressedInSaveFile detected");
|
||||
#endif
|
||||
_pos = 0;
|
||||
_wrapped->seek(0, SEEK_SET);
|
||||
_zlibErr = inflateReset(&_stream);
|
||||
if (_zlibErr != Z_OK)
|
||||
return;
|
||||
_stream.next_in = _buf;
|
||||
_stream.avail_in = 0;
|
||||
}
|
||||
|
||||
offset = newPos - _pos;
|
||||
|
||||
if (offset < 0)
|
||||
error("Backward seeking not supported in compressed savefiles");
|
||||
|
||||
// We could implement backward seeking, but it is tricky to do efficiently.
|
||||
// A simple solution would be to restart the whole decompression from the
|
||||
// start of the file. Or we could decompress the whole file in one go
|
||||
// in the constructor, and wrap it into a MemoryReadStream -- but that
|
||||
// would be rather wasteful. As long as we don't need it, I'd rather not
|
||||
// implement this at all. -- Fingolfin
|
||||
|
||||
// Skip the given amount of data (very inefficient if one tries to skip
|
||||
// huge amounts of data, but usually client code will only skip a few
|
||||
// bytes, so this should be fine.
|
||||
|
||||
@@ -113,7 +113,10 @@ KyraEngine_v1::kReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekab
|
||||
if (loadThumbnail) {
|
||||
header.thumbnail = new Graphics::Surface();
|
||||
assert(header.thumbnail);
|
||||
Graphics::loadThumbnail(*in, *header.thumbnail);
|
||||
if (!Graphics::loadThumbnail(*in, *header.thumbnail)) {
|
||||
delete header.thumbnail;
|
||||
header.thumbnail = 0;
|
||||
}
|
||||
} else {
|
||||
Graphics::skipThumbnailHeader(*in);
|
||||
}
|
||||
|
||||
@@ -184,18 +184,8 @@ bool ScummEngine::loadState(int slot, bool compat) {
|
||||
}
|
||||
|
||||
// Since version 52 a thumbnail is saved directly after the header.
|
||||
if (hdr.ver >= VER(52)) {
|
||||
uint32 type = in->readUint32BE();
|
||||
// Check for the THMB header. Also, work around a bug which caused
|
||||
// the chunk type (incorrectly) to be written in LE on LE machines.
|
||||
if (! (type == MKID_BE('THMB') || (hdr.ver < VER(55) && type == MKID_BE('BMHT')))){
|
||||
warning("Can not load thumbnail");
|
||||
delete in;
|
||||
return false;
|
||||
}
|
||||
uint32 size = in->readUint32BE();
|
||||
in->skip(size - 8);
|
||||
}
|
||||
if (hdr.ver >= VER(52))
|
||||
skipThumbnailHeader(in);
|
||||
|
||||
// Since version 56 we save additional information about the creation of
|
||||
// the save game and the save time.
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Scumm {
|
||||
* only saves/loads those which are valid for the version of the savegame
|
||||
* which is being loaded/saved currently.
|
||||
*/
|
||||
#define CURRENT_VER 74
|
||||
#define CURRENT_VER 75
|
||||
|
||||
/**
|
||||
* An auxillary macro, used to specify savegame versions. We use this instead
|
||||
|
||||
@@ -636,9 +636,11 @@ public:
|
||||
|
||||
protected:
|
||||
Graphics::Surface *loadThumbnail(Common::SeekableReadStream *file);
|
||||
bool loadInfos(Common::SeekableReadStream *file, InfoStuff *stuff);
|
||||
void saveThumbnail(Common::WriteStream *file);
|
||||
void skipThumbnailHeader(Common::SeekableReadStream *file);
|
||||
|
||||
void saveInfos(Common::WriteStream* file);
|
||||
bool loadInfos(Common::SeekableReadStream *file, InfoStuff *stuff);
|
||||
|
||||
int32 _engineStartTime;
|
||||
int32 _pauseStartTime;
|
||||
|
||||
@@ -33,11 +33,8 @@
|
||||
namespace Scumm {
|
||||
|
||||
Graphics::Surface *ScummEngine::loadThumbnail(Common::SeekableReadStream *file) {
|
||||
// TODO: Until backwards seeking in compressed save files is not supported
|
||||
// We can not use this.
|
||||
|
||||
//if (!Graphics::checkThumbnailHeader(*file))
|
||||
// return 0;
|
||||
if (!Graphics::checkThumbnailHeader(*file))
|
||||
return 0;
|
||||
|
||||
Graphics::Surface *thumb = new Graphics::Surface();
|
||||
assert(thumb);
|
||||
@@ -50,25 +47,13 @@ Graphics::Surface *ScummEngine::loadThumbnail(Common::SeekableReadStream *file)
|
||||
}
|
||||
|
||||
void ScummEngine::saveThumbnail(Common::OutSaveFile *file) {
|
||||
// Until we support no thumbnails in the SCUMM save formats for NDS
|
||||
// we save a dummy thumbnail.
|
||||
//
|
||||
// TODO: Actually all what has to be done about it, is to update
|
||||
// the code in engines/scumm/saveload.o which skips the saveheader.
|
||||
// Currently impossible because of lacking backward seek support for
|
||||
// compressed save files.
|
||||
// When we change that code to use the new API from graphics/thumbnail.h
|
||||
// it should be all fine to save no header at all for NDS.
|
||||
|
||||
Graphics::Surface thumb;
|
||||
|
||||
#if !defined(__DS__)
|
||||
if (!createThumbnailFromScreen(&thumb))
|
||||
Graphics::saveThumbnail(*file);
|
||||
#endif
|
||||
thumb.create(kThumbnailWidth, kThumbnailHeight2, sizeof(uint16));
|
||||
}
|
||||
|
||||
Graphics::saveThumbnail(*file, thumb);
|
||||
thumb.free();
|
||||
void ScummEngine::skipThumbnailHeader(Common::SeekableReadStream *file) {
|
||||
Graphics::skipThumbnailHeader(*file);
|
||||
}
|
||||
|
||||
} // end of namespace Scumm
|
||||
|
||||
@@ -91,7 +91,7 @@ bool skipThumbnailHeader(Common::SeekableReadStream &in) {
|
||||
uint32 position = in.pos();
|
||||
ThumbnailHeader header;
|
||||
|
||||
if (!loadHeader(in, header, true)) {
|
||||
if (!loadHeader(in, header, false)) {
|
||||
in.seek(position, SEEK_SET);
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user