[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