[Scummvm-cvs-logs] scummvm master -> acd4cf82e23493e357261eea564a5eaafb6e2647
Littleboy
littleboy22 at gmail.com
Tue Jul 31 07:19:50 CEST 2012
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
acd4cf82e2 LASTEXPRESS: Implement savegame write compression
Commit: acd4cf82e23493e357261eea564a5eaafb6e2647
https://github.com/scummvm/scummvm/commit/acd4cf82e23493e357261eea564a5eaafb6e2647
Author: Littleboy (littleboy at scummvm.org)
Date: 2012-07-30T22:19:05-07:00
Commit Message:
LASTEXPRESS: Implement savegame write compression
Changed paths:
engines/lastexpress/game/savegame.cpp
engines/lastexpress/game/savegame.h
diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp
index 8eda463..54ba45e 100644
--- a/engines/lastexpress/game/savegame.cpp
+++ b/engines/lastexpress/game/savegame.cpp
@@ -73,6 +73,10 @@ uint32 SavegameStream::read(void *dataPtr, uint32 dataSize) {
return readCompressed(dataPtr, dataSize);
#endif
+ return readUncompressed(dataPtr, dataSize);
+}
+
+uint32 SavegameStream::readUncompressed(void *dataPtr, uint32 dataSize) {
if ((int32)dataSize > size() - pos()) {
dataSize = size() - pos();
_eos = true;
@@ -84,18 +88,182 @@ uint32 SavegameStream::read(void *dataPtr, uint32 dataSize) {
return dataSize;
}
-void SavegameStream::process() {
+void SavegameStream::writeBuffer(uint8 value, bool onlyValue) {
+ if (_bufferOffset == -1)
+ _bufferOffset = 0;
+
+ if (_bufferOffset == 256) {
+ _bufferOffset = 0;
+ Common::MemoryWriteStreamDynamic::write(_buffer, 256);
+ }
+
+ if (onlyValue || value < 0xFB)
+ _buffer[_bufferOffset] = value;
+ else
+ _buffer[_bufferOffset] = 0xFE;
+
+ _offset++;
+ _bufferOffset++;
+
+ if (!onlyValue && value >= 0xFB)
+ {
+ if (_bufferOffset == 256) {
+ _bufferOffset = 0;
+ Common::MemoryWriteStreamDynamic::write(_buffer, 256);
+ }
+
+ _buffer[_bufferOffset] = value;
+
+ _bufferOffset++;
+ _offset++;
+ }
+}
+
+uint32 SavegameStream::process() {
_enableCompression = !_enableCompression;
- // TODO Flush compression buffer
+#if DISABLE_COMPRESSION
+ return 0;
+#else
+ switch (_status) {
+ default:
+ break;
+
+ case kStatusReading:
+ _status = kStatusReady;
+ if (_bufferOffset != -1 && _bufferOffset != 256) {
+ seek(_bufferOffset - 256, SEEK_CUR);
+ _bufferOffset = -1;
+ }
+ break;
+
+ case kStatusWriting:
+ switch (_valueCount) {
+ default:
+ break;
+
+ case 1:
+ writeBuffer(_previousValue, false);
+ break;
+
+ case 2:
+ if (_previousValue) {
+ writeBuffer(0xFF, true);
+ writeBuffer(_repeatCount, true);
+ writeBuffer(_previousValue, true);
+ break;
+ }
+
+ if (_repeatCount == 3) {
+ writeBuffer(0xFB, true);
+ break;
+ }
+
+ if (_repeatCount == -1) {
+ writeBuffer(0xFC, true);
+ break;
+ }
+
+ writeBuffer(0xFD, true);
+ writeBuffer(_repeatCount, true);
+ break;
+ }
+
+ if (_bufferOffset != -1 && _bufferOffset != 0) {
+ Common::MemoryWriteStreamDynamic::write(_buffer, _bufferOffset);
+ _bufferOffset = -1;
+ }
+ break;
+ }
+
+ _status = kStatusReady;
+ _valueCount = 0;
+ uint32 offset = _offset;
+ _offset = 0;
+ return offset;
+#endif
}
uint32 SavegameStream::writeCompressed(const void *dataPtr, uint32 dataSize) {
- error("[SavegameStream::writeCompressed] Compression not implemented!");
+ if (_status == kStatusReading)
+ error("[SavegameStream::writeCompressed] Error: Compression buffer is in read mode.");
+
+ _status = kStatusWriting;
+ byte *data = (byte *)dataPtr;
+
+ while (dataSize) {
+ switch (_valueCount) {
+ default:
+ error("[SavegameStream::writeCompressed] Invalid value count (%d)", _valueCount);
+
+ case 0:
+ _previousValue = *data++;
+ _valueCount = 1;
+ break;
+
+ case 1:
+ if (*data != _previousValue) {
+ writeBuffer(_previousValue, false);
+ _previousValue = *data;
+ } else {
+ _valueCount = 2;
+ _repeatCount = 2;
+ }
+
+ ++data;
+ break;
+
+ case 2:
+ if (*data != _previousValue || _repeatCount >= 255) {
+ if (_previousValue) {
+ writeBuffer(0xFF, true);
+ writeBuffer(_repeatCount, true);
+ writeBuffer(_previousValue, true);
+
+ _previousValue = *data++;
+ _valueCount = 1;
+ break;
+ }
+
+ if (_repeatCount == 3) {
+ writeBuffer(0xFB, true);
+
+ _previousValue = *data++;
+ _valueCount = 1;
+ break;
+ }
+
+ if (_repeatCount == -1) {
+ writeBuffer(0xFC, true);
+
+ _previousValue = *data++;
+ _valueCount = 1;
+ break;
+ }
+
+ writeBuffer(0xFD, true);
+ writeBuffer(_repeatCount, true);
+
+ _previousValue = *data++;
+ _valueCount = 1;
+ }
+
+ ++data;
+ ++_repeatCount;
+ break;
+ }
+
+ --dataSize;
+ }
+
+ return _offset;
}
uint32 SavegameStream::readCompressed(void *dataPtr, uint32 dataSize) {
+ if (_status == kStatusWriting)
+ error("[SavegameStream::writeCompressed] Error: Compression buffer is in write mode.");
+
error("[SavegameStream::readCompressed] Compression not implemented!");
}
diff --git a/engines/lastexpress/game/savegame.h b/engines/lastexpress/game/savegame.h
index dc16a16..8866fd3 100644
--- a/engines/lastexpress/game/savegame.h
+++ b/engines/lastexpress/game/savegame.h
@@ -95,9 +95,9 @@ public:
_bufferOffset = -1;
_valueCount = 0;
_previousValue = 0;
- _field_15F = 0;
+ _repeatCount = 0;
_offset = 0;
- _status = 0;
+ _status = kStatusReady;
memset(_buffer, 0, 256);
}
@@ -109,24 +109,34 @@ public:
uint32 read(void *dataPtr, uint32 dataSize);
uint32 write(const void *dataPtr, uint32 dataSize);
- void process();
+ uint32 process();
private:
+ enum CompressedStreamStatus {
+ kStatusReady,
+ kStatusReading,
+ kStatusWriting
+ };
+
+ uint32 readUncompressed(void *dataPtr, uint32 dataSize);
+
// Compressed data
uint32 writeCompressed(const void *dataPtr, uint32 dataSize);
uint32 readCompressed(void *dataPtr, uint32 dataSize);
+ void writeBuffer(uint8 value, bool onlyValue);
+
private:
bool _eos;
// Compression handling
- bool _enableCompression;
- int _bufferOffset;
- int _valueCount;
- byte _previousValue;
- byte _field_15F;
- int _offset;
- int _status;
+ bool _enableCompression;
+ int16 _bufferOffset;
+ byte _valueCount;
+ byte _previousValue;
+ int16 _repeatCount;
+ uint32 _offset;
+ CompressedStreamStatus _status;
byte _buffer[256];
};
More information about the Scummvm-git-logs
mailing list