[Scummvm-cvs-logs] CVS: residual smush.cpp,1.28,1.29 smush.h,1.13,1.14

James Brown ender at users.sourceforge.net
Fri Mar 19 03:01:04 CET 2004


Update of /cvsroot/scummvm/residual
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28404

Modified Files:
	smush.cpp smush.h 
Log Message:
In-memory zlib decompression of SMUSH. Crashes when playing the second smush animation (the message tube in-game one)... not sure why yet.


Index: smush.cpp
===================================================================
RCS file: /cvsroot/scummvm/residual/smush.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- smush.cpp	3 Mar 2004 21:43:34 -0000	1.28
+++ smush.cpp	19 Mar 2004 10:51:04 -0000	1.29
@@ -205,97 +205,9 @@
 bool Smush::play(const char *filename, int x, int y) {
 	stop();
 
-	// Tempfile version of decompression code
-	#ifdef ZLIB_MEMORY
-		// zlibFile version of code. Experimental.
-		// Load the video
-		if (!setupAnim(filename, x, y))
-			return false;
-	#else
-		char tmpOut[256];
-		FILE *tmp = ResourceLoader::instance()->openNewStream(filename);
-		FILE *outFile = NULL;
-		sprintf(tmpOut, "smush.temp");
-
-		if (tmp != NULL) {
-			z_stream z;
-			char inBuf[1024], outBuf[1024], flags;
-			int status = 0;
-
-			warning("Decompressing SMUSH cutscene %s - This may take a minute", filename);
-			fread(inBuf, 4, sizeof(byte), tmp);		//	Header, Method, Flags
-			flags = inBuf[3];
-			fread(inBuf, 6, sizeof(byte), tmp);		// 	XFlags
-
-			if (((flags & 0x04) != 0) || ((flags & 0x10) != 0))	// Misc
-				error("Unsupported header flag");
-
-			if ((flags & 0x08) != 0) {				// Name
-				printf("Decompressing ");
-				do {
-					fread(inBuf, 1, sizeof(char), tmp);
-					printf("%c", inBuf[0]);
-				} while(inBuf[0] != 0);
-				printf("\n");
-			}
-
-			if ((flags & 0x02) != 0)				// CRC
-				fread(inBuf, 2, sizeof(byte), tmp);
-
-			z.zalloc = NULL;
-			z.zfree = NULL;
-			z.opaque = Z_NULL;
-
-			if (inflateInit2(&z, -15) != Z_OK)
-			error("Smush::play() - inflateInit error");
-	
-			z.next_in = (Bytef *)inBuf;
-			z.avail_in = (uInt)fread(inBuf, 1, sizeof(inBuf), tmp);
-			z.next_out = (Bytef *)outBuf;
-			z.avail_out = sizeof(outBuf);
-
-			for (;;) {
-				if (z.avail_in == 0) {
-					z.next_in = (Bytef *)inBuf;
-					z.avail_in = (uInt)fread(inBuf, 1, sizeof(inBuf), tmp);
-				}
-
-				status = inflate(&z, Z_NO_FLUSH);
-				if (status == Z_STREAM_END) {
-					if (sizeof(outBuf) - z.avail_out) {
-						if (outFile == NULL)
-							outFile = fopen(tmpOut, "wb");
-						fwrite(outBuf, 1, sizeof(outBuf) - z.avail_out, outFile);
-					}
-					break;
-				}
-
-				if (status != Z_OK) {
-					warning("Smush::play() - Error inflating stream (%d) [-3 means bad data]", status);
-					return false;
-				}
-
-				if (z.avail_out == 0) {
-					if (outFile == NULL)
-						outFile = fopen(tmpOut, "wb");
-
-					fwrite(outBuf, 1, sizeof(outBuf), outFile);
-					z.next_out = (Bytef *)outBuf;
-					z.avail_out = sizeof(outBuf);
-				}
-			}
-
-			inflateEnd(&z);
-			fclose(outFile);
-			warning("Smush::play() Open okay for %s!\n", filename);
-		} else {
-			return false;
-		}
-
-		// Load the video
-		if (!setupAnim(tmpOut, x, y))
-			return false;
-	#endif
+	// Load the video
+	if (!setupAnim(filename, x, y))
+		return false;
 
 	handleFramesHeader();
 
@@ -320,246 +232,8 @@
 	return true;
 }
 
-FILE *File::fopenNoCase(const char *filename, const char *directory, const char *mode) {
-	FILE *file;
-	char buf[512];
-	char *ptr;
-
-	assert(directory);
-	strcpy(buf, directory);
-
-#ifdef WIN32
-	// Fix for Win98 issue related with game directory pointing to root drive ex. "c:\"
-	if ((buf[0] != 0) && (buf[1] == ':') && (buf[2] == '\\') && (buf[3] == 0)) {
-		buf[2] = 0;
-	}
-#endif
-
-	// Record the length of the dir name (so we can cut of anything trailing it
-	// later, when we try with different file names).
-	const int dirLen = (int)strlen(buf);
-
-	if (dirLen > 0) {
-		strcat(buf, "/");	// prevent double /
-	}
-	strcat(buf, filename);
-
-	file = fopen(buf, mode);
-	if (file)
-		return file;
-
-	const char *dirs[] = {
-		"",
-		"video/",
-		"VIDEO/",
-	};
-
-	for (int dirIdx = 0; dirIdx < ARRAYSIZE(dirs); dirIdx++) {
-		buf[dirLen] = 0;
-		strcat(buf, dirs[dirIdx]);
-		int len = (int)strlen(buf);
-		strcat(buf, filename);
-
-		ptr = buf + len;
-		do
-			*ptr = toupper(*ptr);
-		while (*ptr++);
-		file = fopen(buf, mode);
-		if (file)
-			return file;
-
-		ptr = buf + len;
-		do
-			*ptr = tolower(*ptr);
-		while (*ptr++);
-		file = fopen(buf, mode);
-		if (file)
-			return file;
-	}
-
-	return NULL;
-}
-
-File::File() {
-	_handle = NULL;
-	_ioFailed = false;
-	_encbyte = 0;
-	_name = 0;
-}
-
-File::~File() {
-	close();
-	delete [] _name;
-}
-
-bool File::open(const char *filename, const char *directory, int mode, byte encbyte) {
-	if (_handle) {
-		warning("File %s already opened", filename);
-		return false;
-	}
-
-	if (filename == NULL || *filename == 0)
-		return false;
-	
-	// If no directory was specified, use the default directory (if any).
-	if (directory == NULL)
-		directory = "";
-
-	clearIOFailed();
-
-	if (mode == kFileReadMode) {
-		_handle = fopenNoCase(filename, directory, "rb");
-		if (_handle == NULL) {
-			warning("File %s not found", filename);
-			return false;
-		}
-	}	else {
-		warning("Only read/write mode supported!");
-		return false;
-	}
-
-	_encbyte = encbyte;
-
-	int len = (int)strlen(filename);
-	if (_name != 0)
-		delete [] _name;
-	_name = new char[len+1];
-	memcpy(_name, filename, len+1);
-
-	return true;
-}
-
-void File::close() {
-	if (_handle)
-		fclose(_handle);
-	_handle = NULL;
-}
-
-bool File::isOpen() {
-	return _handle != NULL;
-}
-
-bool File::ioFailed() {
-	return _ioFailed != 0;
-}
-
-void File::clearIOFailed() {
-	_ioFailed = false;
-}
-
-bool File::eof() {
-	if (_handle == NULL) {
-		error("File is not open!");
-		return false;
-	}
-
-	return feof(_handle) != 0;
-}
-
-uint32 File::pos() {
-	if (_handle == NULL) {
-		error("File is not open!");
-		return 0;
-	}
-
-	return ftell(_handle);
-}
-
-uint32 File::size() {
-	if (_handle == NULL) {
-		error("File is not open!");
-		return 0;
-	}
-
-	uint32 oldPos = ftell(_handle);
-	fseek(_handle, 0, SEEK_END);
-	uint32 length = ftell(_handle);
-	fseek(_handle, oldPos, SEEK_SET);
-
-	return length;
-}
-
-void File::seek(int32 offs, int whence) {
-	if (_handle == NULL) {
-		error("File is not open!");
-		return;
-	}
-
-	if (fseek(_handle, offs, whence) != 0)
-		clearerr(_handle);
-}
-
-uint32 File::read(void *ptr, uint32 len) {
-	byte *ptr2 = (byte *)ptr;
-	uint32 real_len;
-
-	if (_handle == NULL) {
-		error("File is not open!");
-		return 0;
-	}
-
-	if (len == 0)
-		return 0;
-
-	real_len = (uint32)fread(ptr2, 1, len, _handle);
-	if (real_len < len) {
-		clearerr(_handle);
-		_ioFailed = true;
-	}
-
-	if (_encbyte != 0) {
-		uint32 t_size = real_len;
-		do {
-			*ptr2++ ^= _encbyte;
-		} while (--t_size);
-	}
-
-	return real_len;
-}
-
-byte File::readByte() {
-	byte b;
-
-	if (_handle == NULL) {
-		error("File is not open!");
-		return 0;
-	}
-
-	if (fread(&b, 1, 1, _handle) != 1) {
-		clearerr(_handle);
-		_ioFailed = true;
-	}
-	return b ^ _encbyte;
-}
-
-uint16 File::readUint16LE() {
-	uint16 a = readByte();
-	uint16 b = readByte();
-	return a | (b << 8);
-}
-
-uint32 File::readUint32LE() {
-	uint32 a = readUint16LE();
-	uint32 b = readUint16LE();
-	return (b << 16) | a;
-}
-
-uint16 File::readUint16BE() {
-	uint16 b = readByte();
-	uint16 a = readByte();
-	return a | (b << 8);
-}
-
-uint32 File::readUint32BE() {
-	uint32 b = readUint16BE();
-	uint32 a = readUint16BE();
-	return (b << 16) | a;
-}
-///////////////////////////////////
-
 zlibFile::zlibFile() {
 	_handle = NULL;
-	usedBuffer = 0;
 }
 
 zlibFile::~zlibFile() {
@@ -568,6 +242,7 @@
 
 bool zlibFile::open(const char *filename) {
 	char flags = 0;
+	inBuf = (char*)calloc(1, 16385);
 
 	if (_handle) {
 		warning("File %s already opened", filename);
@@ -583,46 +258,39 @@
 		return false;
 	}
 
-	warning("zlibFile %s opening...", filename);
-
 	// Read in the GZ header
-	fread(inBuf, 4, sizeof(char), _handle); // Header, Method, Flags
-	flags = inBuf[3];
-	fread(inBuf, 6, sizeof(char), _handle); // XFlags
+	fread(inBuf, 2, sizeof(char), _handle);				// Header
+	fread(inBuf, 1, sizeof(char), _handle);				// Method
+	fread(inBuf, 1, sizeof(char), _handle); flags=inBuf[0];		// Flags
+	fread(inBuf, 6, sizeof(char), _handle);				// XFlags
 
-	if (((flags & 0x04) != 0) || ((flags & 0x10) != 0)) // Misc
+	if (((flags & 0x04) != 0) || ((flags & 0x10) != 0))		// Xtra & Comment
 		error("Unsupported header flag");
 
-	if ((flags & 0x08) != 0) { // Name
-		printf("Decompressing ");
+	if ((flags & 0x08) != 0) {					// Orig. Name
 		do {
 			fread(inBuf, 1, sizeof(char), _handle);
 			printf("%c", inBuf[0]);
 		} while(inBuf[0] != 0);
-		printf("\n");
-}
+	}
 
 	if ((flags & 0x02) != 0) // CRC
 		fread(inBuf, 2, sizeof(char), _handle);
 
+	memset(inBuf, 0, 16384);			// Zero buffer (debug)
 	stream.zalloc = NULL;
 	stream.zfree = NULL;
 	stream.opaque = Z_NULL;
 
 	if (inflateInit2(&stream, -15) != Z_OK)
-		error("zlibFile::(constructor) - inflateInit2 failed");
+		error("inflateInit2 failed");
 
-	// Initial buffer pump
-	stream.next_in = (Bytef*)inBuf;
-	stream.avail_in = fread(inBuf, 1, sizeof(inBuf), _handle);
-	stream.next_out = (Bytef *)outBuf;
-	stream.avail_out = sizeof(outBuf);
-	if (!fillZlibBuffer()) {
-		warning("Error during initial zlib decompression for %s", filename);
-		return false;
-	}
+	stream.next_in = NULL;
+	stream.next_out = NULL;
+	stream.avail_in = 0;
+	stream.avail_out = 16384;
 
-	warning("zlibFile %s opened!", filename);
+	warning("zlibFile %s opened", filename);
 	return true;
 }
 
@@ -630,6 +298,7 @@
 	if (_handle)
 		fclose(_handle);
 	_handle = NULL;
+	free(inBuf);
 }
 
 bool zlibFile::isOpen() {
@@ -656,7 +325,8 @@
 }
 
 uint32 zlibFile::read(void *ptr, uint32 len) {
-	byte *ptr2 = (byte *)ptr;
+	int result = Z_OK;
+	bool fileEOF = false;
 
 	if (_handle == NULL) {
 		error("File is not open!");
@@ -665,80 +335,47 @@
 
 	if (len == 0)
 		return 0;
-	int bufferLeft = sizeof(outBuf) - usedBuffer;
-
-	printf("zlibFile::read(%d). usedBuffer: %d. bufferLeft: %d\n", len, usedBuffer, bufferLeft);
-
-	// Do we need to get more than one buffer-read to complete this request?
-	if (len > bufferLeft) {
-		int maxBuffer = sizeof(outBuf);
-		int ptr2Pos = bufferLeft;
-		int neededAmount = len - bufferLeft;
-		
-		memcpy(ptr2, outBuf+usedBuffer, bufferLeft);	// Copy what we've got
 
-		while (neededAmount > 0) {
-			fillZlibBuffer();
+	stream.next_out = (Bytef*)ptr;
+	stream.avail_out = len;
 
-			if (neededAmount > maxBuffer) {
-				memcpy(ptr2+ptr2Pos, outBuf, maxBuffer);
- 
-				neededAmount-=maxBuffer;
-				ptr2Pos+=maxBuffer;
-				usedBuffer+=maxBuffer;
-			} else {
-				memcpy(ptr2+ptr2Pos, outBuf, neededAmount);
-				usedBuffer+=neededAmount;
-				neededAmount = 0;
+	fileDone = false;
+	while (stream.avail_out != 0) {
+		if (stream.avail_in == 0) {	// !eof
+	        	stream.avail_in = fread(inBuf, 1, 16384, _handle);
+			if (stream.avail_in == 0) {
+				fileEOF = true;
+				break;
 			}
+			stream.next_in = (Byte*)inBuf;
 		}
-	} else {
-		memcpy(ptr2, outBuf + usedBuffer, len);
-		usedBuffer+=len;
-	}
-	return len;
-}
- 
-bool zlibFile::fillZlibBuffer() {
-	int status = 0;
 
-	if (stream.avail_in == 0) {
-		stream.next_in = (Bytef*)inBuf;
-		stream.avail_in = fread(inBuf, 1, sizeof(inBuf), _handle);
-	}
-
-	status = inflate(&stream, Z_NO_FLUSH);
-	if (status == Z_STREAM_END) {
-		if (sizeof(outBuf) - stream.avail_out)
-			warning("fillZlibBuffer: End of buffer");
-		return true;
-	}
-
-	if (status != Z_OK) {
-		warning("Smush::play() - Error inflating stream (%d) [-3 means bad data]", status);
-		return false;
-	}
-
-
-	if (stream.avail_out == 0) {
-		stream.next_out = (Bytef*)outBuf;
-		stream.avail_out = sizeof(outBuf);
+		result = inflate(&stream, Z_NO_FLUSH);
+		if (result == Z_STREAM_END) {	// EOF
+			warning("Stream ended");
+			fileDone = true;
+			break;
+		}
+		if (result == Z_DATA_ERROR) {
+			warning("Decompression error");
+			fileDone = true;
+			break;
+		}
+		if (result != Z_OK || fileEOF) {
+			warning("Unknown decomp result: %d/%d\n", result, fileEOF);
+			fileDone = true;
+			break;
+		}
 	}
-	usedBuffer = 0;
 
-	return true;
+	return (int)(len - stream.avail_out);
 }
-
+ 
 byte zlibFile::readByte() {
-	if (_handle == NULL) {
-		error("File is not open!");
-		return 0;
-	}
-
-	if (usedBuffer >= sizeof(outBuf))
-		fillZlibBuffer();
+	unsigned char c;
 
-	return outBuf[usedBuffer++];
+	read(&c, 1);
+	return c;
 }
 
 uint16 zlibFile::readUint16LE() {

Index: smush.h
===================================================================
RCS file: /cvsroot/scummvm/residual/smush.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- smush.h	3 Mar 2004 21:43:34 -0000	1.13
+++ smush.h	19 Mar 2004 10:51:04 -0000	1.14
@@ -18,10 +18,6 @@
 #ifndef SMUSH_PLAYER_H
 #define SMUSH_PLAYER_H
 
-// Use experimental (probably non-functional) in-memory zlib decompression.
-// Leave undefined to use WORKING tempfile version.
-//#define ZLIB_MEMORY
-
 #include "bits.h"
 #include "debug.h"
 #include <cstring>
@@ -30,53 +26,16 @@
 #include "blocky16.h"
 #include "mixer/mixer.h"
 
-class File {
-private:
-
-	FILE * _handle;
-	bool _ioFailed;
-	uint8 _encbyte;
-	char *_name;	// For debugging
-
-	static FILE *fopenNoCase(const char *filename, const char *directory, const char *mode);
-
-public:
-	enum {
-		kFileReadMode = 1,
-	};
-	
-	File();
-	virtual ~File();
-	bool open(const char *filename, const char *directory = NULL, int mode = kFileReadMode, byte encbyte = 0);
-	void close();
-	bool isOpen();
-	bool ioFailed();
-	void clearIOFailed();
-	bool eof();
-	uint32 pos();
-	uint32 size();
-	const char *name() const { return _name; }
-	void seek(int32 offs, int whence = SEEK_SET);
-	uint32 read(void *ptr, uint32 size);
-	uint8 readByte();
-	uint16 readUint16LE();
-	uint32 readUint32LE();
-	uint16 readUint16BE();
-	uint32 readUint32BE();
-	void setEnc(byte value) { _encbyte = value; }
-};
-
 class zlibFile {
 private:
 	FILE *_handle;
-	z_stream stream;	// zlib stream
-	uint32 usedBuffer;	// how much of outBuf has been processed by ::read*()
-	char inBuf[1024], outBuf[1024]; // Buffers for decompression
-	bool fillZlibBuffer();
+	z_stream stream;	// Zlib stream
+	char *inBuf;		// Buffer for decompression
+	bool fileDone;
 
 public:
 	zlibFile();
-	virtual ~zlibFile();
+	~zlibFile();
 	bool open(const char *filename);
 	void close();
 	bool isOpen();
@@ -97,11 +56,7 @@
 private:
 	int32 _nbframes;
 	Blocky16 _blocky16;
-	#ifdef ZLIB_MEMORY
-		zlibFile _file;
-	#else
-		File _file;
-	#endif
+	zlibFile _file;
 	PlayingSoundHandle _soundHandle;
 
 	int32 _frame;





More information about the Scummvm-git-logs mailing list