[Scummvm-cvs-logs] SF.net SVN: scummvm:[34035] scummvm/branches/branch-0-12-0/engines/cine

buddha_ at users.sourceforge.net buddha_ at users.sourceforge.net
Tue Aug 19 14:17:18 CEST 2008


Revision: 34035
          http://scummvm.svn.sourceforge.net/scummvm/?rev=34035&view=rev
Author:   buddha_
Date:     2008-08-19 12:17:17 +0000 (Tue, 19 Aug 2008)

Log Message:
-----------
Backport of r34033: Fix for bug #2057637: FW: Spaceship glitches in demo (regression).
This was caused by assuming in-place decompression is ok, it wasn't,
although AFAIK the original did decompression in-place too.
Changed unpacking to be done not in-place and the glitch vanished.
Also changed the unpacker to also handle uncompressed input data.

Modified Paths:
--------------
    scummvm/branches/branch-0-12-0/engines/cine/part.cpp
    scummvm/branches/branch-0-12-0/engines/cine/part.h
    scummvm/branches/branch-0-12-0/engines/cine/unpack.cpp
    scummvm/branches/branch-0-12-0/engines/cine/unpack.h

Modified: scummvm/branches/branch-0-12-0/engines/cine/part.cpp
===================================================================
--- scummvm/branches/branch-0-12-0/engines/cine/part.cpp	2008-08-19 11:55:20 UTC (rev 34034)
+++ scummvm/branches/branch-0-12-0/engines/cine/part.cpp	2008-08-19 12:17:17 UTC (rev 34035)
@@ -125,13 +125,13 @@
 		unpackedSize = packedSize = f.size();
 	}
 	uint8 *buf = new uint8[unpackedSize];
-	f.read(buf, packedSize);
-	if (packedSize != unpackedSize) {
-		CineUnpacker cineUnpacker;
-		if (!cineUnpacker.unpack(buf, packedSize, buf, unpackedSize)) {
-			error("Error while unpacking 'vol.cnf' data");
-		}
+	uint8 *packedBuf = new uint8[packedSize];
+	f.read(packedBuf, packedSize);
+	CineUnpacker cineUnpacker;
+	if (!cineUnpacker.unpack(packedBuf, packedSize, buf, unpackedSize)) {
+		error("Error while unpacking 'vol.cnf' data");
 	}
+	delete[] packedBuf;
 	uint8 *p = buf;
 	int resourceFilesCount = READ_BE_UINT16(p); p += 2;
 	int entrySize = READ_BE_UINT16(p); p += 2;
@@ -212,7 +212,8 @@
 	return -1;
 }
 
-void readFromPart(int16 idx, byte *dataPtr) {
+void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize) {
+	assert(maxSize >= partBuffer[idx].packedSize);
 	setMouseCursor(MOUSE_CURSOR_DISK);
 
 	g_cine->_partFileHandle.seek(partBuffer[idx].offset, SEEK_SET);
@@ -221,17 +222,17 @@
 
 byte *readBundleFile(int16 foundFileIdx) {
 	assert(foundFileIdx >= 0 && foundFileIdx < numElementInPart);
+	bool error = false;
 	byte *dataPtr = (byte *)calloc(partBuffer[foundFileIdx].unpackedSize, 1);
-	if (partBuffer[foundFileIdx].unpackedSize != partBuffer[foundFileIdx].packedSize) {
-		byte *unpackBuffer = (byte *)malloc(partBuffer[foundFileIdx].packedSize);
-		readFromPart(foundFileIdx, unpackBuffer);
-		CineUnpacker cineUnpacker;
-		if (!cineUnpacker.unpack(unpackBuffer, partBuffer[foundFileIdx].packedSize, dataPtr, partBuffer[foundFileIdx].unpackedSize)) {
-			warning("Error unpacking '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName);
-		}
-		free(unpackBuffer);
-	} else {
-		readFromPart(foundFileIdx, dataPtr);
+	byte *packedData = (byte *)calloc(partBuffer[foundFileIdx].packedSize, 1);
+	assert(dataPtr && packedData);
+	readFromPart(foundFileIdx, packedData, partBuffer[foundFileIdx].packedSize);
+	CineUnpacker cineUnpacker;
+	error = !cineUnpacker.unpack(packedData, partBuffer[foundFileIdx].packedSize, dataPtr, partBuffer[foundFileIdx].unpackedSize);
+	free(packedData);
+
+	if (error) {
+		warning("Error unpacking '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName);
 	}
 
 	return dataPtr;

Modified: scummvm/branches/branch-0-12-0/engines/cine/part.h
===================================================================
--- scummvm/branches/branch-0-12-0/engines/cine/part.h	2008-08-19 11:55:20 UTC (rev 34034)
+++ scummvm/branches/branch-0-12-0/engines/cine/part.h	2008-08-19 12:17:17 UTC (rev 34035)
@@ -44,7 +44,7 @@
 
 int16 findFileInBundle(const char *fileName);
 
-void readFromPart(int16 idx, byte *dataPtr);
+void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize);
 
 byte *readBundleFile(int16 foundFileIdx);
 byte *readBundleSoundFile(const char *entryName, uint32 *size = 0);

Modified: scummvm/branches/branch-0-12-0/engines/cine/unpack.cpp
===================================================================
--- scummvm/branches/branch-0-12-0/engines/cine/unpack.cpp	2008-08-19 11:55:20 UTC (rev 34034)
+++ scummvm/branches/branch-0-12-0/engines/cine/unpack.cpp	2008-08-19 12:17:17 UTC (rev 34035)
@@ -100,6 +100,14 @@
 	_dstBegin = dst;
 	_dstEnd   = dst + dstLen;
 
+	// Handle already unpacked data here
+	if (srcLen == dstLen) {
+		// Source length is same as destination length so the source
+		// data is already unpacked. Let's just copy it then.
+		memcpy(dst, src, srcLen);
+		return true;
+	}
+
 	// Initialize other variables
 	_src = _srcBegin + srcLen - 4;
 	uint32 unpackedLength = readSource(); // Unpacked length in bytes

Modified: scummvm/branches/branch-0-12-0/engines/cine/unpack.h
===================================================================
--- scummvm/branches/branch-0-12-0/engines/cine/unpack.h	2008-08-19 11:55:20 UTC (rev 34034)
+++ scummvm/branches/branch-0-12-0/engines/cine/unpack.h	2008-08-19 12:17:17 UTC (rev 34035)
@@ -35,14 +35,14 @@
  * A LZ77 style decompressor for Delphine's data files
  * used in at least Future Wars and Operation Stealth.
  * @note Works backwards in the source and destination buffers.
- * @note Can work with source and destination in the same buffer if there's space.
+ * @warning Having the source and destination in the same buffer when unpacking can cause errors!
  */
 class CineUnpacker {
 public:
 	/**
 	 * Unpacks packed data from the source buffer to the destination buffer.
-	 * @warning Do NOT call this on data that is not packed.
-	 * @note Source and destination buffer pointers can be the same as long as there's space for the unpacked data.
+	 * @note You may call this on already unpacked data but then source length must be equal to destination length.
+	 * @warning The source and destination should not point to the same buffer. If they do, errors may occur!
 	 * @param src Pointer to the source buffer.
 	 * @param srcLen Length of the source buffer.
 	 * @param dst Pointer to the destination buffer.


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list