diff options
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/save/savefile.cpp | 104 | ||||
-rw-r--r-- | engines/gob/save/savefile.h | 12 | ||||
-rw-r--r-- | engines/gob/save/savehandler.cpp | 44 | ||||
-rw-r--r-- | engines/gob/save/savehandler.h | 7 | ||||
-rw-r--r-- | engines/gob/save/saveload_inca2.cpp | 2 | ||||
-rw-r--r-- | engines/gob/save/saveload_v3.cpp | 2 |
6 files changed, 126 insertions, 45 deletions
diff --git a/engines/gob/save/savefile.cpp b/engines/gob/save/savefile.cpp index 3869ea2def..d472ef600b 100644 --- a/engines/gob/save/savefile.cpp +++ b/engines/gob/save/savefile.cpp @@ -85,6 +85,16 @@ bool SaveHeader::verify(Common::ReadStream &stream) const { return !stream.err(); } +bool SaveHeader::operator==(const SaveHeader &header) const { + return (_type == header._type) && + (_version == header._version) && + (_size == header._size); +} + +bool SaveHeader::operator!=(const SaveHeader &header) const { + return !(*this == header); +} + bool SaveHeader::verifyReadSize(Common::ReadStream &stream) { // Compare the header with the stream's content, expect for the size @@ -263,21 +273,29 @@ bool SavePartVars::writeInto(uint32 var, uint32 offset, uint32 size) const { return true; } -SavePartSprite::SavePartSprite(uint32 width, uint32 height) { +SavePartSprite::SavePartSprite(uint32 width, uint32 height, bool trueColor) { assert((width > 0) && (height > 0)); _width = width; _height = height; + _oldFormat = false; + _trueColor = trueColor; + _header.setType(kID); _header.setVersion(kVersion); - // width + height + sprite + palette - _header.setSize(4 + 4 + _width * _height + 768); - _dataSprite = new byte[_width * _height]; + _spriteSize = _width * _height; + if (_trueColor) + _spriteSize *= 3; + + // width + height + color + sprite + palette + _header.setSize(4 + 4 + 1 + _spriteSize + 768); + + _dataSprite = new byte[_spriteSize]; _dataPalette = new byte[768]; - memset(_dataSprite, 0, _width * _height); + memset(_dataSprite, 0, _spriteSize); memset(_dataPalette, 0, 768); } @@ -287,8 +305,28 @@ SavePartSprite::~SavePartSprite() { } bool SavePartSprite::read(Common::ReadStream &stream) { - if (!_header.verify(stream)) - return false; + SaveHeader header; + header.read(stream); + + if (_header != header) { + if (!_trueColor) { + // Header validation failed, trying again with the old version + + _header.setVersion(1); + _header.setSize(_header.getSize() - 1); + + if (_header != header) + // Nope, isn't it either + return false; + + _oldFormat = true; + + _header.setVersion(kVersion); + _header.setSize(_header.getSize() + 1); + + } else + return false; + } // The sprite's dimensions have to fit if (stream.readUint32LE() != _width) @@ -296,8 +334,13 @@ bool SavePartSprite::read(Common::ReadStream &stream) { if (stream.readUint32LE() != _height) return false; + // If it's in the current format, the true color flag has to be the same too + if (!_oldFormat) + if (stream.readByte() != _trueColor) + return false; + // Sprite data - if (stream.read(_dataSprite, _width * _height) != (_width * _height)) + if (stream.read(_dataSprite, _spriteSize) != _spriteSize) return false; // Palette data @@ -314,9 +357,10 @@ bool SavePartSprite::write(Common::WriteStream &stream) const { // The sprite's dimensions stream.writeUint32LE(_width); stream.writeUint32LE(_height); + stream.writeByte(_trueColor); // Sprite data - if (stream.write(_dataSprite, _width * _height) != (_width * _height)) + if (stream.write(_dataSprite, _spriteSize) != _spriteSize) return false; // Palette data @@ -339,17 +383,29 @@ bool SavePartSprite::readSprite(const Surface &sprite) { if (((uint32)sprite.getHeight()) != _height) return false; - // Only 8bit sprites supported for now - if (sprite.getBPP() != 1) - return false; + if (_trueColor) { + if (sprite.getBPP() <= 1) + return false; - memcpy(_dataSprite, sprite.getData(), _width * _height); + Graphics::PixelFormat pixelFormat = g_system->getScreenFormat(); + + byte *data = _dataSprite; + ConstPixel pixel = sprite.get(); + for (uint32 i = 0; i < (_width * _height); i++, ++pixel, data += 3) + pixelFormat.colorToRGB(pixel.get(), data[0], data[1], data[2]); + + } else { + if (sprite.getBPP() != 1) + return false; + + memcpy(_dataSprite, sprite.getData(), _width * _height); + } return true; } bool SavePartSprite::readSpriteRaw(const byte *data, uint32 size) { - if (size != (_width * _height)) + if (size != _spriteSize) return false; memcpy(_dataSprite, data, size); @@ -369,11 +425,23 @@ bool SavePartSprite::writeSprite(Surface &sprite) const { if (((uint32)sprite.getHeight()) != _height) return false; - // Only 8bit sprites supported for now - if (sprite.getBPP() != 1) - return false; + if (_trueColor) { + if (sprite.getBPP() <= 1) + return false; + + Graphics::PixelFormat pixelFormat = g_system->getScreenFormat(); - memcpy(sprite.getData(), _dataSprite, _width * _height); + const byte *data = _dataSprite; + Pixel pixel = sprite.get(); + for (uint32 i = 0; i < (_width * _height); i++, ++pixel, data += 3) + pixel.set(pixelFormat.RGBToColor(data[0], data[1], data[2])); + + } else { + if (sprite.getBPP() != 1) + return false; + + memcpy(sprite.getData(), _dataSprite, _spriteSize); + } return true; } diff --git a/engines/gob/save/savefile.h b/engines/gob/save/savefile.h index 980616bb74..eeee03847a 100644 --- a/engines/gob/save/savefile.h +++ b/engines/gob/save/savefile.h @@ -53,6 +53,9 @@ public: SaveHeader(uint32 type = 0, uint32 version = 0, uint32 size = 0); + bool operator==(const SaveHeader &header) const; + bool operator!=(const SaveHeader &header) const; + /** Read the header out of a stream into this class. */ bool read(Common::ReadStream &stream); /** Read the header out of a stream and checks it against this class's contents. */ @@ -151,10 +154,10 @@ private: /** A save part holding a sprite. */ class SavePartSprite : public SavePart { public: - static const uint32 kVersion = 1; + static const uint32 kVersion = 2; static const uint32 kID = MKID_BE('SPRT'); - SavePartSprite(uint32 width, uint32 height); + SavePartSprite(uint32 width, uint32 height, bool trueColor = false); ~SavePartSprite(); bool read(Common::ReadStream &stream); @@ -177,6 +180,11 @@ private: uint32 _width; uint32 _height; + uint32 _spriteSize; + + bool _oldFormat; + bool _trueColor; + byte *_dataSprite; byte *_dataPalette; }; diff --git a/engines/gob/save/savehandler.cpp b/engines/gob/save/savehandler.cpp index 8a20665140..848578abce 100644 --- a/engines/gob/save/savehandler.cpp +++ b/engines/gob/save/savehandler.cpp @@ -279,12 +279,11 @@ bool TempSpriteHandler::load(int16 dataVar, int32 size, int32 offset) { } bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) { - SurfacePtr sprite; - if (isDummy(size)) return true; - if (!createSprite(dataVar, size, offset, &sprite)) + SurfacePtr sprite = createSprite(dataVar, size, offset); + if (!sprite) return false; // Save the sprite @@ -292,42 +291,47 @@ bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) { return false; // Handle palette - if (usesPalette(size)) { + if (usesPalette(size)) if (!_sprite->readPalette((const byte *)_vm->_global->_pPaletteDesc->vgaPal)) return false; - } return true; } -bool TempSpriteHandler::createSprite(int16 dataVar, int32 size, - int32 offset, SurfacePtr *sprite) { - +bool TempSpriteHandler::create(uint32 width, uint32 height, bool trueColor) { delete _sprite; _sprite = 0; + // Create a new temporary sprite + _sprite = new SavePartSprite(width, height, trueColor); + + return true; +} + +bool TempSpriteHandler::createFromSprite(int16 dataVar, int32 size, int32 offset) { + return createSprite(dataVar, size, offset) != 0; +} + +SurfacePtr TempSpriteHandler::createSprite(int16 dataVar, int32 size, int32 offset) { + SurfacePtr sprt; + // Sprite requested? if (!isSprite(size)) - return false; + return sprt; // Index sane? int index = getIndex(size); if ((index < 0) || (index >= SPRITES_COUNT)) - return false; - - SurfacePtr sprt = _vm->_draw->_spritesArray[index]; + return sprt; // Sprite exists? - if (!sprt) - return false; + if (!(sprt = _vm->_draw->_spritesArray[index])) + return sprt; - // Create a new temporary sprite - _sprite = new SavePartSprite(sprt->getWidth(), sprt->getHeight()); + if (!create(sprt->getWidth(), sprt->getHeight(), sprt->getBPP() > 1)) + sprt.reset(); - if (sprite) - *sprite = sprt; - - return true; + return sprt; } // A size of 0 means no proper sprite should be saved/loaded, diff --git a/engines/gob/save/savehandler.h b/engines/gob/save/savehandler.h index c6370947e2..51fbad0b98 100644 --- a/engines/gob/save/savehandler.h +++ b/engines/gob/save/savehandler.h @@ -140,9 +140,8 @@ public: bool load(int16 dataVar, int32 size, int32 offset); bool save(int16 dataVar, int32 size, int32 offset); - /** Create a fitting sprite. */ - bool createSprite(int16 dataVar, int32 size, - int32 offset, SurfacePtr *sprite = 0); + bool create(uint32 width, uint32 height, bool trueColor); + bool createFromSprite(int16 dataVar, int32 size, int32 offset); protected: SavePartSprite *_sprite; @@ -155,6 +154,8 @@ protected: static int getIndex(int32 size); /** Determine whether the palette should be used too. */ static bool usesPalette(int32 size); + + SurfacePtr createSprite(int16 dataVar, int32 size, int32 offset); }; /** A handler for notes. */ diff --git a/engines/gob/save/saveload_inca2.cpp b/engines/gob/save/saveload_inca2.cpp index e32c4fd25c..68c76c3f2b 100644 --- a/engines/gob/save/saveload_inca2.cpp +++ b/engines/gob/save/saveload_inca2.cpp @@ -322,7 +322,7 @@ bool SaveLoad_Inca2::ScreenshotHandler::load(int16 dataVar, int32 size, int32 of return false; } - if (!TempSpriteHandler::createSprite(dataVar, size, offset)) + if (!TempSpriteHandler::createFromSprite(dataVar, size, offset)) return false; if (!_gameHandler->loadScreenshot(slot, _sprite)) diff --git a/engines/gob/save/saveload_v3.cpp b/engines/gob/save/saveload_v3.cpp index bb60f94725..098b8e1160 100644 --- a/engines/gob/save/saveload_v3.cpp +++ b/engines/gob/save/saveload_v3.cpp @@ -439,7 +439,7 @@ bool SaveLoad_v3::ScreenshotHandler::load(int16 dataVar, int32 size, int32 offse if ((slot >= kSlotCount) || (slotRem != 0)) return false; - if (!TempSpriteHandler::createSprite(dataVar, size, offset)) + if (!TempSpriteHandler::createFromSprite(dataVar, size, offset)) return false; if (!_gameHandler->loadScreenshot(slot, _sprite)) |