aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/save/savefile.cpp104
-rw-r--r--engines/gob/save/savefile.h12
-rw-r--r--engines/gob/save/savehandler.cpp44
-rw-r--r--engines/gob/save/savehandler.h7
-rw-r--r--engines/gob/save/saveload_inca2.cpp2
-rw-r--r--engines/gob/save/saveload_v3.cpp2
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))