aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner/savefile.cpp
diff options
context:
space:
mode:
authorPeter Kohaut2018-11-21 23:16:15 +0100
committerPeter Kohaut2018-11-24 08:39:03 +0100
commit824ecc0aad325c54f34c8fb7f64cf4df71c53090 (patch)
tree109abb14609bacaac2c0b1b2ed42e67a8cd2c5ec /engines/bladerunner/savefile.cpp
parent44b68a0aeb92d6dc6b6d1b3260ec5f82c529b9f0 (diff)
downloadscummvm-rg350-824ecc0aad325c54f34c8fb7f64cf4df71c53090.tar.gz
scummvm-rg350-824ecc0aad325c54f34c8fb7f64cf4df71c53090.tar.bz2
scummvm-rg350-824ecc0aad325c54f34c8fb7f64cf4df71c53090.zip
BLADERUNNER: Preliminary saving & loading support
Saving and loading is accessible via ScummVM dialogs. No in-game UI support yet. It is possible to load saves from original game via debugger console. ScummVM saves have additional header and are incompatibile with original game.
Diffstat (limited to 'engines/bladerunner/savefile.cpp')
-rw-r--r--engines/bladerunner/savefile.cpp92
1 files changed, 79 insertions, 13 deletions
diff --git a/engines/bladerunner/savefile.cpp b/engines/bladerunner/savefile.cpp
index 3528a6bb82..b0fb1e7fd6 100644
--- a/engines/bladerunner/savefile.cpp
+++ b/engines/bladerunner/savefile.cpp
@@ -27,13 +27,76 @@
#include "common/rect.h"
#include "common/savefile.h"
+#include "common/system.h"
+
+#include "graphics/thumbnail.h"
namespace BladeRunner {
-SaveFileWriteStream::SaveFileWriteStream()
- : MemoryWriteStreamDynamic(DisposeAfterUse::YES) {
+bool SaveFile::readHeader(Common::SeekableReadStream &in, SaveFileHeader &header, bool skipThumbnail) {
+ SaveFileReadStream s(in);
+
+ if (s.readUint32BE() != kTag) {
+ warning("No header found in save file");
+ return false;
+ }
+
+ header._version = s.readByte();
+ if (header._version != kVersion) {
+ warning("Unsupported version of save file %u, supported is %u", header._version, kVersion);
+ return false;
+ }
+
+ header._name = s.readStringSz(kNameLength);
+
+ header._year = s.readUint16LE();
+ header._month = s.readUint16LE();
+ header._day = s.readUint16LE();
+ header._hour = s.readUint16LE();
+ header._minute = s.readUint16LE();
+
+ header._thumbnail = nullptr;
+
+ if (!skipThumbnail) {
+ header._thumbnail = new Graphics::Surface();
+
+ int32 pos = s.pos();
+
+ s.skip(4); //skip size;
+
+ void *thumbnailData = new byte[kThumbnailSize];
+ s.read(thumbnailData, kThumbnailSize);
+
+ // TODO: cleanup - remove magic constants
+ header._thumbnail->init(80, 60, 160, thumbnailData, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+
+ s.seek(pos);
+ }
+
+ return true;
+}
+
+bool SaveFile::writeHeader(Common::WriteStream &out, SaveFileHeader &header) {
+ SaveFileWriteStream s(out);
+
+ s.writeUint32BE(kTag);
+ s.writeByte(kVersion);
+
+ s.writeStringSz(header._name, kNameLength);
+
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ s.writeUint16LE(td.tm_year + 1900);
+ s.writeUint16LE(td.tm_mon + 1);
+ s.writeUint16LE(td.tm_mday);
+ s.writeUint16LE(td.tm_hour);
+ s.writeUint16LE(td.tm_min);
+
+ return true;
}
+SaveFileWriteStream::SaveFileWriteStream(Common::WriteStream &s) : _s(s) {}
+
void SaveFileWriteStream::debug(char *p) {
write(p, strlen(p) + 1);
}
@@ -48,7 +111,7 @@ void SaveFileWriteStream::writeInt(int v) {
writeUint32LE(v);
}
-void SaveFileWriteStream::writeFloat(int v) {
+void SaveFileWriteStream::writeFloat(float v) {
writeFloatLE(v);
}
@@ -80,7 +143,7 @@ void SaveFileWriteStream::writeRect(const Common::Rect &v) {
writeUint32LE(v.bottom);
}
-void SaveFileWriteStream::writeBoundingBox(const BoundingBox &v) {
+void SaveFileWriteStream::writeBoundingBox(const BoundingBox &v, bool serialized) {
float x0, y0, z0, x1, y1, z1;
v.getXYZ(&x0, &y0, &z0, &x1, &y1, &z1);
@@ -92,14 +155,13 @@ void SaveFileWriteStream::writeBoundingBox(const BoundingBox &v) {
writeFloatLE(z1);
// Bounding boxes have a lot of extra data that's never actually used
- for (int i = 0; i != 96; ++i) {
+ int count = serialized ? 96 : 64;
+ for (int i = 0; i < count; ++i) {
writeFloatLE(0.0f);
}
}
-SaveFileReadStream::SaveFileReadStream(const byte *dataPtr, uint32 dataSize)
- : MemoryReadStream(dataPtr, dataSize, DisposeAfterUse::YES) {
-}
+SaveFileReadStream::SaveFileReadStream(Common::SeekableReadStream &s) : _s(s) {}
int SaveFileReadStream::readInt() {
return readUint32LE();
@@ -114,10 +176,10 @@ bool SaveFileReadStream::readBool() {
}
Common::String SaveFileReadStream::readStringSz(int sz) {
- char *buf = (char *)malloc(sz);
+ char *buf = new char[sz];
read(buf, sz);
Common::String result = buf;
- free(buf);
+ delete[] buf;
return result;
}
@@ -145,18 +207,22 @@ Common::Rect SaveFileReadStream::readRect() {
return result;
}
-BoundingBox SaveFileReadStream::readBoundingBox() {
+BoundingBox SaveFileReadStream::readBoundingBox(bool serialized) {
float x0, y0, z0, x1, y1, z1;
x0 = readFloatLE();
y0 = readFloatLE();
z0 = readFloatLE();
+
x1 = readFloatLE();
y1 = readFloatLE();
z1 = readFloatLE();
- // Bounding boxes have a lot of extra data that's never actually used
- skip(384);
+ // Bounding boxes have a lot of extra data that's never actually used, and there two formats for storing bounding boxes.
+ int count = serialized ? 96 : 64;
+ for (int i = 0; i < count; ++i) {
+ readFloatLE();
+ }
return BoundingBox(x0, y0, z0, x1, y1, z1);
}