[Scummvm-cvs-logs] SF.net SVN: scummvm:[33128] residual/trunk

aquadran at users.sourceforge.net aquadran at users.sourceforge.net
Sun Jul 20 17:02:10 CEST 2008


Revision: 33128
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33128&view=rev
Author:   aquadran
Date:     2008-07-20 15:00:50 +0000 (Sun, 20 Jul 2008)

Log Message:
-----------
added savefile support

Modified Paths:
--------------
    residual/trunk/dists/msvc7/residual.vcproj
    residual/trunk/dists/msvc71/residual.vcproj
    residual/trunk/dists/msvc8/residual.vcproj
    residual/trunk/dists/msvc9/residual.vcproj
    residual/trunk/engine/backend/driver.h
    residual/trunk/engine/backend/module.mk
    residual/trunk/engine/backend/sdl/driver_sdl.cpp
    residual/trunk/engine/backend/sdl/driver_sdl.h
    residual/trunk/engine/main.cpp
    residual/trunk/engine/savegame.cpp
    residual/trunk/engine/savegame.h

Added Paths:
-----------
    residual/trunk/engine/backend/saves/
    residual/trunk/engine/backend/saves/compressed/
    residual/trunk/engine/backend/saves/compressed/compressed-saves.cpp
    residual/trunk/engine/backend/saves/compressed/compressed-saves.h
    residual/trunk/engine/backend/saves/default/
    residual/trunk/engine/backend/saves/default/default-saves.cpp
    residual/trunk/engine/backend/saves/default/default-saves.h
    residual/trunk/engine/backend/saves/savefile.cpp

Modified: residual/trunk/dists/msvc7/residual.vcproj
===================================================================
--- residual/trunk/dists/msvc7/residual.vcproj	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/dists/msvc7/residual.vcproj	2008-07-20 15:00:50 UTC (rev 33128)
@@ -21,7 +21,7 @@
 				AdditionalOptions="/wd 4996"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\"
-				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;LUA_ADD_CUSTOM_FOPEN"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;LUA_ADD_CUSTOM_FOPEN;USE_ZLIB"
 				RuntimeLibrary="1"
 				EnableEnhancedInstructionSet="2"
 				FloatingPointModel="2"
@@ -178,9 +178,6 @@
 				RelativePath="..\..\common\memorypool.h">
 			</File>
 			<File
-				RelativePath="..\..\common\module.mk">
-			</File>
-			<File
 				RelativePath="..\..\common\mutex.cpp">
 			</File>
 			<File
@@ -724,6 +721,34 @@
 						</File>
 					</Filter>
 				</Filter>
+				<Filter
+					Name="saves">
+					<File
+						RelativePath="..\..\engine\backend\saves\savefile.cpp">
+					</File>
+					<Filter
+						Name="compressed">
+						<File
+							RelativePath="..\..\engine\backend\saves\compressed\compressed-saves.cpp"
+							>
+						</File>
+						<File
+							RelativePath="..\..\engine\backend\saves\compressed\compressed-saves.h"
+							>
+						</File>
+					</Filter>
+					<Filter
+						Name="default">
+						<File
+							RelativePath="..\..\engine\backend\saves\default\default-saves.cpp"
+							>
+						</File>
+						<File
+							RelativePath="..\..\engine\backend\saves\default\default-saves.h"
+							>
+						</File>
+					</Filter>
+				</Filter>
 			</Filter>
 		</Filter>
 		<Filter

Modified: residual/trunk/dists/msvc71/residual.vcproj
===================================================================
--- residual/trunk/dists/msvc71/residual.vcproj	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/dists/msvc71/residual.vcproj	2008-07-20 15:00:50 UTC (rev 33128)
@@ -21,7 +21,7 @@
 				AdditionalOptions="/wd 4996"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\"
-				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;LUA_ADD_CUSTOM_FOPEN"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;LUA_ADD_CUSTOM_FOPEN;USE_ZLIB"
 				RuntimeLibrary="1"
 				EnableEnhancedInstructionSet="2"
 				FloatingPointModel="2"
@@ -192,9 +192,6 @@
 				RelativePath="..\..\common\memorypool.h">
 			</File>
 			<File
-				RelativePath="..\..\common\module.mk">
-			</File>
-			<File
 				RelativePath="..\..\common\mutex.cpp">
 			</File>
 			<File
@@ -738,6 +735,34 @@
 						</File>
 					</Filter>
 				</Filter>
+				<Filter
+					Name="saves">
+					<File
+						RelativePath="..\..\engine\backend\saves\savefile.cpp">
+					</File>
+					<Filter
+						Name="compressed">
+						<File
+							RelativePath="..\..\engine\backend\saves\compressed\compressed-saves.cpp"
+							>
+						</File>
+						<File
+							RelativePath="..\..\engine\backend\saves\compressed\compressed-saves.h"
+							>
+						</File>
+					</Filter>
+					<Filter
+						Name="default">
+						<File
+							RelativePath="..\..\engine\backend\saves\default\default-saves.cpp"
+							>
+						</File>
+						<File
+							RelativePath="..\..\engine\backend\saves\default\default-saves.h"
+							>
+						</File>
+					</Filter>
+				</Filter>
 			</Filter>
 		</Filter>
 		<Filter

Modified: residual/trunk/dists/msvc8/residual.vcproj
===================================================================
--- residual/trunk/dists/msvc8/residual.vcproj	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/dists/msvc8/residual.vcproj	2008-07-20 15:00:50 UTC (rev 33128)
@@ -42,7 +42,7 @@
 				AdditionalOptions="/wd 4996"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\"
-				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;LUA_ADD_CUSTOM_FOPEN"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;LUA_ADD_CUSTOM_FOPEN;USE_ZLIB"
 				RuntimeLibrary="1"
 				EnableEnhancedInstructionSet="2"
 				FloatingPointModel="2"
@@ -276,10 +276,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\common\module.mk"
-				>
-			</File>
-			<File
 				RelativePath="..\..\common\mutex.cpp"
 				>
 			</File>
@@ -1002,6 +998,38 @@
 						</File>
 					</Filter>
 				</Filter>
+				<Filter
+					Name="saves"
+					>
+					<File
+						RelativePath="..\..\engine\backend\saves\savefile.cpp"
+						>
+					</File>
+					<Filter
+						Name="compressed"
+						>
+						<File
+							RelativePath="..\..\engine\backend\saves\compressed\compressed-saves.cpp"
+							>
+						</File>
+						<File
+							RelativePath="..\..\engine\backend\saves\compressed\compressed-saves.h"
+							>
+						</File>
+					</Filter>
+					<Filter
+						Name="default"
+						>
+						<File
+							RelativePath="..\..\engine\backend\saves\default\default-saves.cpp"
+							>
+						</File>
+						<File
+							RelativePath="..\..\engine\backend\saves\default\default-saves.h"
+							>
+						</File>
+					</Filter>
+				</Filter>
 			</Filter>
 		</Filter>
 		<Filter

Modified: residual/trunk/dists/msvc9/residual.vcproj
===================================================================
--- residual/trunk/dists/msvc9/residual.vcproj	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/dists/msvc9/residual.vcproj	2008-07-20 15:00:50 UTC (rev 33128)
@@ -43,7 +43,7 @@
 				AdditionalOptions="/wd 4996"
 				Optimization="0"
 				AdditionalIncludeDirectories="..\..\"
-				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;LUA_ADD_CUSTOM_FOPEN"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;LUA_ADD_CUSTOM_FOPEN;USE_ZLIB"
 				RuntimeLibrary="1"
 				EnableEnhancedInstructionSet="2"
 				FloatingPointModel="2"
@@ -281,10 +281,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\common\module.mk"
-				>
-			</File>
-			<File
 				RelativePath="..\..\common\mutex.cpp"
 				>
 			</File>
@@ -1007,6 +1003,38 @@
 						</File>
 					</Filter>
 				</Filter>
+				<Filter
+					Name="saves"
+					>
+					<File
+						RelativePath="..\..\engine\backend\saves\savefile.cpp"
+						>
+					</File>
+					<Filter
+						Name="compressed"
+						>
+						<File
+							RelativePath="..\..\engine\backend\saves\compressed\compressed-saves.cpp"
+							>
+						</File>
+						<File
+							RelativePath="..\..\engine\backend\saves\compressed\compressed-saves.h"
+							>
+						</File>
+					</Filter>
+					<Filter
+						Name="default"
+						>
+						<File
+							RelativePath="..\..\engine\backend\saves\default\default-saves.cpp"
+							>
+						</File>
+						<File
+							RelativePath="..\..\engine\backend\saves\default\default-saves.h"
+							>
+						</File>
+					</Filter>
+				</Filter>
 			</Filter>
 		</Filter>
 		<Filter

Modified: residual/trunk/engine/backend/driver.h
===================================================================
--- residual/trunk/engine/backend/driver.h	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/engine/backend/driver.h	2008-07-20 15:00:50 UTC (rev 33128)
@@ -44,6 +44,10 @@
 class Timer;
 class FilesystemFactory;
 
+namespace Common {
+	class SaveFileManager;
+}
+
 namespace Audio {
 	class MixerImpl;
 	class Mixer;
@@ -301,6 +305,8 @@
 	 * @return FilesystemFactory* The specific factory for the current architecture.
 	 */
 	virtual FilesystemFactory *getFilesystemFactory() = 0;
+
+	virtual Common::SaveFileManager *getSavefileManager() = 0;
 	//@}
 
 protected:

Modified: residual/trunk/engine/backend/module.mk
===================================================================
--- residual/trunk/engine/backend/module.mk	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/engine/backend/module.mk	2008-07-20 15:00:50 UTC (rev 33128)
@@ -4,6 +4,9 @@
 	fs/amigaos4/amigaos4-fs-factory.o \
 	fs/posix/posix-fs-factory.o \
 	fs/windows/windows-fs-factory.o \
+	saves/savefile.o \
+	saves/default/default-saves.o \
+	saves/compressed/compressed-saves.o \
 	default-timer.o
 
 # Include common rules


Property changes on: residual/trunk/engine/backend/saves
___________________________________________________________________
Added: svn:ignore
   + .deps
*.d
*.o



Property changes on: residual/trunk/engine/backend/saves/compressed
___________________________________________________________________
Added: svn:ignore
   + .deps
*.d
*.o


Added: residual/trunk/engine/backend/saves/compressed/compressed-saves.cpp
===================================================================
--- residual/trunk/engine/backend/saves/compressed/compressed-saves.cpp	                        (rev 0)
+++ residual/trunk/engine/backend/saves/compressed/compressed-saves.cpp	2008-07-20 15:00:50 UTC (rev 33128)
@@ -0,0 +1,301 @@
+/* Residual - Virtual machine to run LucasArts' 3D adventure games
+ *
+ * Residual is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/savefile.h"
+#include "common/util.h"
+#include "common/debug.h"
+#include "engine/backend/saves/compressed/compressed-saves.h"
+
+#if defined(USE_ZLIB)
+#include <zlib.h>
+
+#if ZLIB_VERNUM < 0x1204
+#error Version 1.2.0.4 or newer of zlib is required for this code
+#endif
+
+/**
+ * A simple wrapper class which can be used to wrap around an arbitrary
+ * other InSaveFile and will then provide on-the-fly decompression support.
+ * Assumes the compressed data to be in gzip format.
+ */
+class CompressedInSaveFile : public Common::InSaveFile {
+protected:
+	enum {
+		BUFSIZE = 16384		// 1 << MAX_WBITS
+	};
+
+	byte	_buf[BUFSIZE];
+
+	Common::InSaveFile *_wrapped;
+	z_stream _stream;
+	int _zlibErr;
+	uint32 _pos;
+	uint32 _origSize;
+
+public:
+
+	CompressedInSaveFile(Common::InSaveFile *w) : _wrapped(w) {
+		assert(w != 0);
+
+		_stream.zalloc = Z_NULL;
+		_stream.zfree = Z_NULL;
+		_stream.opaque = Z_NULL;
+
+		// Verify file header is correct once more
+		w->seek(0, SEEK_SET);
+		uint16 header = w->readUint16BE();
+		assert(header == 0x1F8B ||
+		       ((header & 0x0F00) == 0x0800 && header % 31 == 0));
+
+		if (header == 0x1F8B) {
+			// Retrieve the original file size
+			w->seek(-4, SEEK_END);
+			_origSize = w->readUint32LE();
+		} else {
+			// Original size not available in zlib format
+			_origSize = 0;
+		}
+		_pos = 0;
+		w->seek(0, SEEK_SET);
+
+		// Adding 32 to windowBits indicates to zlib that it is supposed to
+		// automatically detect whether gzip or zlib headers are used for
+		// the compressed file. This feature was added in zlib 1.2.0.4,
+		// released 10 August 2003.
+		// Note: This is *crucial* for savegame compatibility, do *not* remove!
+		_zlibErr = inflateInit2(&_stream, MAX_WBITS + 32);
+		if (_zlibErr != Z_OK)
+			return;
+
+		// Setup input buffer
+		_stream.next_in = _buf;
+		_stream.avail_in = 0;
+	}
+
+	~CompressedInSaveFile() {
+		inflateEnd(&_stream);
+		delete _wrapped;
+	}
+
+	bool ioFailed() const { return (_zlibErr != Z_OK) && (_zlibErr != Z_STREAM_END); }
+	void clearIOFailed() { /* errors here are not recoverable!  */ }
+
+	uint32 read(void *dataPtr, uint32 dataSize) {
+		_stream.next_out = (byte *)dataPtr;
+		_stream.avail_out = dataSize;
+
+		// Keep going while we get no error
+		while (_zlibErr == Z_OK && _stream.avail_out) {
+			if (_stream.avail_in == 0 && !_wrapped->eos()) {
+				// If we are out of input data: Read more data, if available.
+				_stream.next_in = _buf;
+				_stream.avail_in = _wrapped->read(_buf, BUFSIZE);
+			}
+			_zlibErr = inflate(&_stream, Z_NO_FLUSH);
+		}
+
+		// Update the position counter
+		_pos += dataSize - _stream.avail_out;
+
+		return dataSize - _stream.avail_out;
+	}
+
+	bool eos() const {
+		return (_zlibErr == Z_STREAM_END);
+		//return _pos == _origSize;
+	}
+	uint32 pos() const {
+		return _pos;
+	}
+	uint32 size() const {
+		return _origSize;
+	}
+	void seek(int32 offset, int whence = SEEK_SET) {
+		int32 newPos = 0;
+		switch(whence) {
+		case SEEK_END:
+			newPos = size() - offset;
+			break;
+		case SEEK_SET:
+			newPos = offset;
+			break;
+		case SEEK_CUR:
+			newPos = _pos + offset;
+		}
+		offset = newPos - _pos;
+
+		if (offset < 0)
+			error("Backward seeking not supported in compressed savefiles");
+
+		// We could implement backward seeking, but it is tricky to do efficiently.
+		// A simple solution would be to restart the whole decompression from the
+		// start of the file. Or we could decompress the whole file in one go
+		// in the constructor, and wrap it into a MemoryReadStream -- but that
+		// would be rather wasteful. As long as we don't need it, I'd rather not
+		// implement this at all. -- Fingolfin
+
+		// Skip the given amount of data (very inefficient if one tries to skip
+		// huge amounts of data, but usually client code will only skip a few
+		// bytes, so this should be fine.
+		byte tmpBuf[1024];
+		while (!ioFailed() && offset > 0) {
+			offset -= read(tmpBuf, MIN((int32)sizeof(tmpBuf), offset));
+		}
+	}
+};
+
+/**
+ * A simple wrapper class which can be used to wrap around an arbitrary
+ * other OutSaveFile and will then provide on-the-fly compression support.
+ * The compressed data is written in the gzip format.
+ */
+class CompressedOutSaveFile : public Common::OutSaveFile {
+protected:
+	enum {
+		BUFSIZE = 16384		// 1 << MAX_WBITS
+	};
+
+	byte	_buf[BUFSIZE];
+	Common::OutSaveFile *_wrapped;
+	z_stream _stream;
+	int _zlibErr;
+
+	void processData(int flushType) {
+		// This function is called by both write() and finalize().
+		while (_zlibErr == Z_OK && (_stream.avail_in || flushType == Z_FINISH)) {
+			if (_stream.avail_out == 0) {
+				if (_wrapped->write(_buf, BUFSIZE) != BUFSIZE) {
+					_zlibErr = Z_ERRNO;
+					break;
+				}
+				_stream.next_out = _buf;
+				_stream.avail_out = BUFSIZE;
+			}
+			_zlibErr = deflate(&_stream, flushType);
+		}
+	}
+
+public:
+	CompressedOutSaveFile(Common::OutSaveFile *w) : _wrapped(w) {
+		assert(w != 0);
+		_stream.zalloc = Z_NULL;
+		_stream.zfree = Z_NULL;
+		_stream.opaque = Z_NULL;
+
+		// Adding 16 to windowBits indicates to zlib that it is supposed to
+		// write gzip headers. This feature was added in zlib 1.2.0.4,
+		// released 10 August 2003.
+		// Note: This is *crucial* for savegame compatibility, do *not* remove!
+		_zlibErr = deflateInit2(&_stream,
+		                 Z_DEFAULT_COMPRESSION,
+		                 Z_DEFLATED,
+		                 MAX_WBITS + 16,
+		                 8,
+                         Z_DEFAULT_STRATEGY);
+		assert(_zlibErr == Z_OK);
+
+		_stream.next_out = _buf;
+		_stream.avail_out = BUFSIZE;
+		_stream.avail_in = 0;
+		_stream.next_in = 0;
+	}
+
+	~CompressedOutSaveFile() {
+		finalize();
+		deflateEnd(&_stream);
+		delete _wrapped;
+	}
+
+	bool ioFailed() const {
+		return (_zlibErr != Z_OK && _zlibErr != Z_STREAM_END) || _wrapped->ioFailed();
+	}
+
+	void clearIOFailed() {
+		// Note: we don't reset the _zlibErr here, as it is not
+		// clear in general ho
+		_wrapped->clearIOFailed();
+	}
+
+	void finalize() {
+		if (_zlibErr != Z_OK)
+			return;
+
+		// Process whatever remaining data there is.
+		processData(Z_FINISH);
+
+		// Since processData only writes out blocks of size BUFSIZE,
+		// we may have to flush some stragglers.
+		uint remainder = BUFSIZE - _stream.avail_out;
+		if (remainder > 0) {
+			if (_wrapped->write(_buf, remainder) != remainder) {
+				_zlibErr = Z_ERRNO;
+			}
+		}
+
+		// Finalize the wrapped savefile, too
+		_wrapped->finalize();
+	}
+
+	uint32 write(const void *dataPtr, uint32 dataSize) {
+		if (ioFailed())
+			return 0;
+
+		// Hook in the new data ...
+		// Note: We need to make a const_cast here, as zlib is not aware
+		// of the const keyword.
+		_stream.next_in = const_cast<byte *>((const byte *)dataPtr);
+		_stream.avail_in = dataSize;
+
+		// ... and flush it to disk
+		processData(Z_NO_FLUSH);
+
+		return dataSize - _stream.avail_in;
+	}
+};
+
+#endif	// USE_ZLIB
+
+Common::InSaveFile *wrapInSaveFile(Common::InSaveFile *toBeWrapped) {
+#if defined(USE_ZLIB)
+	if (toBeWrapped) {
+		uint16 header = toBeWrapped->readUint16BE();
+		bool isCompressed = (header == 0x1F8B ||
+				     ((header & 0x0F00) == 0x0800 &&
+				      header % 31 == 0));
+		toBeWrapped->seek(-2, SEEK_CUR);
+		if (isCompressed)
+			return new CompressedInSaveFile(toBeWrapped);
+	}
+#endif
+	return toBeWrapped;
+}
+
+Common::OutSaveFile *wrapOutSaveFile(Common::OutSaveFile *toBeWrapped) {
+#if defined(USE_ZLIB)
+	if (toBeWrapped)
+		return new CompressedOutSaveFile(toBeWrapped);
+#endif
+	return toBeWrapped;
+}


Property changes on: residual/trunk/engine/backend/saves/compressed/compressed-saves.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: residual/trunk/engine/backend/saves/compressed/compressed-saves.h
===================================================================
--- residual/trunk/engine/backend/saves/compressed/compressed-saves.h	                        (rev 0)
+++ residual/trunk/engine/backend/saves/compressed/compressed-saves.h	2008-07-20 15:00:50 UTC (rev 33128)
@@ -0,0 +1,53 @@
+/* Residual - Virtual machine to run LucasArts' 3D adventure games
+ *
+ * Residual is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BACKEND_SAVES_COMPRESSED_H
+#define BACKEND_SAVES_COMPRESSED_H
+
+#include "common/savefile.h"
+
+/**
+ * Take an arbitrary InSaveFile and wrap it in a high level InSaveFile which
+ * provides transparent on-the-fly decompression support.
+ * Assumes the data it retrieves from the wrapped savefile to be either
+ * uncompressed or in gzip format. In the former case, the original
+ * savefile is returned unmodified (and in particular, not wrapped).
+ *
+ * It is safe to call this with a NULL parameter (in this case, NULL is
+ * returned).
+ */
+Common::InSaveFile *wrapInSaveFile(Common::InSaveFile *toBeWrapped);
+
+/**
+ * Take an arbitrary OutSaveFile and wrap it in a high level OutSaveFile which
+ * provides transparent on-the-fly compression support.
+ * The compressed data is written in the gzip format.
+ *
+ * It is safe to call this with a NULL parameter (in this case, NULL is
+ * returned).
+ */
+Common::OutSaveFile *wrapOutSaveFile(Common::OutSaveFile *toBeWrapped);
+
+#endif


Property changes on: residual/trunk/engine/backend/saves/compressed/compressed-saves.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native


Property changes on: residual/trunk/engine/backend/saves/default
___________________________________________________________________
Added: svn:ignore
   + .deps
*.d
*.o


Added: residual/trunk/engine/backend/saves/default/default-saves.cpp
===================================================================
--- residual/trunk/engine/backend/saves/default/default-saves.cpp	                        (rev 0)
+++ residual/trunk/engine/backend/saves/default/default-saves.cpp	2008-07-20 15:00:50 UTC (rev 33128)
@@ -0,0 +1,287 @@
+/* Residual - Virtual machine to run LucasArts' 3D adventure games
+ *
+ * Residual is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#if !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
+
+#include "common/savefile.h"
+#include "common/util.h"
+#include "common/fs.h"
+#include "common/file.h"
+//#include "common/config-manager.h"
+#include "engine/backend/saves/default/default-saves.h"
+#include "engine/backend/saves/compressed/compressed-saves.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#if defined(UNIX) || defined(__SYMBIAN32__)
+#include <sys/stat.h>
+#endif
+
+
+class StdioSaveFile : public Common::InSaveFile, public Common::OutSaveFile {
+private:
+	FILE *fh;
+public:
+	StdioSaveFile(const char *filename, bool saveOrLoad) {
+		fh = ::fopen(filename, (saveOrLoad? "wb" : "rb"));
+	}
+	~StdioSaveFile() {
+		if (fh)
+			::fclose(fh);
+	}
+
+	bool eos() const { return feof(fh) != 0; }
+	bool ioFailed() const { return ferror(fh) != 0; }
+	void clearIOFailed() { clearerr(fh); }
+
+	bool isOpen() const { return fh != 0; }
+
+	uint32 read(void *dataPtr, uint32 dataSize) {
+		assert(fh);
+		return fread(dataPtr, 1, dataSize, fh);
+	}
+	uint32 write(const void *dataPtr, uint32 dataSize) {
+		assert(fh);
+		return fwrite(dataPtr, 1, dataSize, fh);
+	}
+
+	uint32 pos() const {
+		assert(fh);
+		return ftell(fh);
+	}
+	uint32 size() const {
+		assert(fh);
+		uint32 oldPos = ftell(fh);
+		fseek(fh, 0, SEEK_END);
+		uint32 length = ftell(fh);
+		fseek(fh, oldPos, SEEK_SET);
+		return length;
+	}
+
+	void seek(int32 offs, int whence = SEEK_SET) {
+		assert(fh);
+		fseek(fh, offs, whence);
+	}
+};
+
+static void join_paths(const char *filename, const char *directory,
+								 char *buf, int bufsize) {
+	buf[bufsize-1] = '\0';
+	strncpy(buf, directory, bufsize-1);
+
+#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
+
+	const int dirLen = strlen(buf);
+
+	if (dirLen > 0) {
+#if defined(__MORPHOS__) || defined(__amigaos4__)
+		if (buf[dirLen-1] != ':' && buf[dirLen-1] != '/')
+#endif
+
+#if !defined(__GP32__)
+		strncat(buf, "/", bufsize-1);	// prevent double /
+#endif
+	}
+	strncat(buf, filename, bufsize-1);
+}
+
+Common::StringList DefaultSaveFileManager::listSavefiles(const char *pattern) {
+	FilesystemNode savePath(getSavePath());
+	FSList savefiles;
+	Common::StringList results;
+	Common::String search(pattern);
+
+	if (savePath.lookupFile(savefiles, search, false, true, 0)) {
+		for (FSList::const_iterator file = savefiles.begin(); file != savefiles.end(); ++file) {
+			results.push_back(file->getName());
+		}
+	}
+
+	return results;
+}
+
+void DefaultSaveFileManager::checkPath(const Common::String &path) {
+	clearError();
+
+#if defined(UNIX) || defined(__SYMBIAN32__)
+	struct stat sb;
+
+	// Check whether the dir exists
+	if (stat(path.c_str(), &sb) == -1) {
+		// The dir does not exist, or stat failed for some other reason.
+		// If the problem was that the path pointed to nothing, try
+		// to create the dir (ENOENT case).
+		switch (errno) {
+		case EACCES:
+			setError(SFM_DIR_ACCESS, "Search or write permission denied: "+path);
+			break;
+#if !defined(__SYMBIAN32__)
+		case ELOOP:
+			setError(SFM_DIR_LOOP, "Too many symbolic links encountered while traversing the path: "+path);
+			break;
+#endif
+		case ENAMETOOLONG:
+			setError(SFM_DIR_NAMETOOLONG, "The path name is too long: "+path);
+			break;
+		case ENOENT:
+			if (mkdir(path.c_str(), 0755) != 0) {
+				// mkdir could fail for various reasons: The parent dir doesn't exist,
+				// or is not writeable, the path could be completly bogus, etc.
+				warning("mkdir for '%s' failed!", path.c_str());
+				perror("mkdir");
+
+				switch (errno) {
+				case EACCES:
+					setError(SFM_DIR_ACCESS, "Search or write permission denied: "+path);
+					break;
+				case EMLINK:
+					setError(SFM_DIR_LINKMAX, "The link count of the parent directory would exceed {LINK_MAX}: "+path);
+					break;
+#if !defined(__SYMBIAN32__)
+				case ELOOP:
+					setError(SFM_DIR_LOOP, "Too many symbolic links encountered while traversing the path: "+path);
+					break;
+#endif
+				case ENAMETOOLONG:
+					setError(SFM_DIR_NAMETOOLONG, "The path name is too long: "+path);
+					break;
+				case ENOENT:
+					setError(SFM_DIR_NOENT, "A component of the path does not exist, or the path is an empty string: "+path);
+					break;
+				case ENOTDIR:
+					setError(SFM_DIR_NOTDIR, "A component of the path prefix is not a directory: "+path);
+					break;
+				case EROFS:
+					setError(SFM_DIR_ROFS, "The parent directory resides on a read-only file system:"+path);
+					break;
+				}
+			}
+			break;
+		case ENOTDIR:
+			setError(SFM_DIR_NOTDIR, "A component of the path prefix is not a directory: "+path);
+			break;
+		}
+	} else {
+		// So stat() succeeded. But is the path actually pointing to a directory?
+		if (!S_ISDIR(sb.st_mode)) {
+			setError(SFM_DIR_NOTDIR, "The given savepath is not a directory: "+path);
+		}
+	}
+#endif
+}
+
+Common::InSaveFile *DefaultSaveFileManager::openForLoading(const char *filename) {
+	// Ensure that the savepath is valid. If not, generate an appropriate error.
+	char buf[256];
+	Common::String savePath = getSavePath();
+	checkPath(savePath);
+
+	if (getError() == SFM_NO_ERROR) {
+		join_paths(filename, savePath.c_str(), buf, sizeof(buf));
+		StdioSaveFile *sf = new StdioSaveFile(buf, false);
+
+		if (!sf->isOpen()) {
+			delete sf;
+			sf = 0;
+		}
+
+		return wrapInSaveFile(sf);
+	} else {
+		return 0;
+	}
+}
+
+Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const char *filename) {
+	// Ensure that the savepath is valid. If not, generate an appropriate error.
+	char buf[256];
+	Common::String savePath = getSavePath();
+	checkPath(savePath);
+
+	if (getError() == SFM_NO_ERROR) {
+		join_paths(filename, savePath.c_str(), buf, sizeof(buf));
+		StdioSaveFile *sf = new StdioSaveFile(buf, true);
+
+		if (!sf->isOpen()) {
+			delete sf;
+			sf = 0;
+		}
+
+		return wrapOutSaveFile(sf);
+	} else {
+		return 0;
+	}
+}
+
+bool DefaultSaveFileManager::removeSavefile(const char *filename) {
+	char buf[256];
+	clearError();
+	Common::String filenameStr;
+	join_paths(filename, getSavePath().c_str(), buf, sizeof(buf));
+
+	if (remove(buf) != 0) {
+#ifndef _WIN32_WCE
+		if (errno == EACCES)
+			setError(SFM_DIR_ACCESS, "Search or write permission denied: "+filenameStr);
+
+		if (errno == ENOENT)
+			setError(SFM_DIR_NOENT, "A component of the path does not exist, or the path is an empty string: "+filenameStr);
+#endif
+		return false;
+	} else {
+		return true;
+	}
+}
+
+Common::String DefaultSaveFileManager::getSavePath() const {
+
+	Common::String dir;
+/*
+	// Try to use game specific savepath from config
+	dir = ConfMan.get("savepath");
+
+	// Work around a bug (#999122) in the original 0.6.1 release of
+	// ScummVM, which would insert a bad savepath value into config files.
+	if (dir == "None") {
+		ConfMan.removeKey("savepath", ConfMan.getActiveDomainName());
+		ConfMan.flushToDisk();
+		dir = ConfMan.get("savepath");
+	}
+
+#ifdef _WIN32_WCE
+	if (dir.empty())
+		dir = ConfMan.get("path");
+#endif
+*/
+	return dir;
+}
+
+#endif // !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)


Property changes on: residual/trunk/engine/backend/saves/default/default-saves.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: residual/trunk/engine/backend/saves/default/default-saves.h
===================================================================
--- residual/trunk/engine/backend/saves/default/default-saves.h	                        (rev 0)
+++ residual/trunk/engine/backend/saves/default/default-saves.h	2008-07-20 15:00:50 UTC (rev 33128)
@@ -0,0 +1,57 @@
+/* Residual - Virtual machine to run LucasArts' 3D adventure games
+ *
+ * Residual is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#if !defined(BACKEND_SAVES_DEFAULT_H) && !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
+#define BACKEND_SAVES_DEFAULT_H
+
+#include "common/savefile.h"
+#include "common/str.h"
+
+/**
+ * Provides a default savefile manager implementation for common platforms.
+ */
+class DefaultSaveFileManager : public Common::SaveFileManager {
+public:
+	virtual Common::StringList listSavefiles(const char *pattern);
+	virtual Common::InSaveFile *openForLoading(const char *filename);
+	virtual Common::OutSaveFile *openForSaving(const char *filename);
+	virtual bool removeSavefile(const char *filename);
+
+protected:
+	/**
+	 * Get the path to the savegame directory.
+	 * Should only be used internally since some platforms
+	 * might implement savefiles in a completely different way.
+	 */
+	virtual Common::String getSavePath() const;
+
+	/**
+	 * Checks the given path for read access, existence, etc.
+	 * Sets the internal error and error message accordingly.
+	 */
+	void checkPath(const Common::String &path);
+};
+
+#endif


Property changes on: residual/trunk/engine/backend/saves/default/default-saves.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: residual/trunk/engine/backend/saves/savefile.cpp
===================================================================
--- residual/trunk/engine/backend/saves/savefile.cpp	                        (rev 0)
+++ residual/trunk/engine/backend/saves/savefile.cpp	2008-07-20 15:00:50 UTC (rev 33128)
@@ -0,0 +1,81 @@
+/* Residual - Virtual machine to run LucasArts' 3D adventure games
+ *
+ * Residual is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the AUTHORS
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/util.h"
+#include "common/savefile.h"
+
+#include <stdio.h>
+#include <string.h>
+
+namespace Common {
+
+bool SaveFileManager::renameSavefile(const char *oldFilename, const char *newFilename) {
+
+	InSaveFile *inFile = 0;
+	OutSaveFile *outFile = 0;
+	uint32 size = 0;
+	void *buffer = 0;
+	bool success = false;
+
+	inFile = openForLoading(oldFilename);
+
+	if (inFile) {
+		size = inFile->size();
+		buffer = malloc(size);
+		assert(buffer);
+
+		outFile = openForSaving(newFilename);
+
+		if (buffer && outFile) {
+			inFile->read(buffer, size);
+			bool error = inFile->ioFailed();
+			delete inFile;
+			inFile = 0;
+
+			if (!error) {
+				outFile->write(buffer, size);
+				outFile->finalize();
+				if (!outFile->ioFailed()) {
+					success = removeSavefile(oldFilename);
+				}
+			}
+		}
+
+		free(buffer);
+		delete outFile;
+		delete inFile;
+	}
+
+	return success;
+}
+
+String SaveFileManager::popErrorDesc() {
+	String err = _errorDesc;
+	clearError();
+
+	return err;
+}
+
+} // End of namespace Common


Property changes on: residual/trunk/engine/backend/saves/savefile.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: residual/trunk/engine/backend/sdl/driver_sdl.cpp
===================================================================
--- residual/trunk/engine/backend/sdl/driver_sdl.cpp	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/engine/backend/sdl/driver_sdl.cpp	2008-07-20 15:00:50 UTC (rev 33128)
@@ -29,6 +29,7 @@
 
 #include "engine/backend/sdl/driver_sdl.h"
 #include "engine/backend/default-timer.h"
+#include "engine/backend/saves/default/default-saves.h"
 
 #ifdef _WIN32
 #include <windows.h>
@@ -324,6 +325,10 @@
 	_timer = new DefaultTimerManager();
 	_timerID = SDL_AddTimer(10, &timer_handler, _timer);
 
+	if (!_savefile) {
+		_savefile = new DefaultSaveFileManager();
+	}
+
 #if !defined(MACOSX)
 	setupIcon();
 #endif
@@ -514,6 +519,11 @@
 	#endif
 }
 
+Common::SaveFileManager *DriverSDL::getSavefileManager() {
+	assert(_savefile);
+	return _savefile;
+}
+
 void DriverSDL::setupIcon() {
 	int w, h, ncols, nbytes, i;
 	unsigned int rgba[256], icon[32 * 32];

Modified: residual/trunk/engine/backend/sdl/driver_sdl.h
===================================================================
--- residual/trunk/engine/backend/sdl/driver_sdl.h	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/engine/backend/sdl/driver_sdl.h	2008-07-20 15:00:50 UTC (rev 33128)
@@ -77,10 +77,12 @@
 
 	void quit();
 	FilesystemFactory *getFilesystemFactory();
+	Common::SaveFileManager *getSavefileManager();
 
 private:
 
 	int _samplesPerSec;
+	Common::SaveFileManager *_savefile;
 	Common::TimerManager *_timer;
 	SDL_TimerID _timerID;
 

Modified: residual/trunk/engine/main.cpp
===================================================================
--- residual/trunk/engine/main.cpp	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/engine/main.cpp	2008-07-20 15:00:50 UTC (rev 33128)
@@ -174,6 +174,7 @@
 	g_localizer = new Localizer();
 	g_smush = new Smush();
 	g_imuse = new Imuse(20);
+	g_saveFileMan = g_driver->getSavefileManager();
 
 	Bitmap *splash_bm = NULL;
 	if (!(g_flags & GF_DEMO))

Modified: residual/trunk/engine/savegame.cpp
===================================================================
--- residual/trunk/engine/savegame.cpp	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/engine/savegame.cpp	2008-07-20 15:00:50 UTC (rev 33128)
@@ -24,8 +24,12 @@
  */
 
 #include "common/debug.h"
+#include "common/savefile.h"
+
 #include "engine/savegame.h"
 
+Common::SaveFileManager *g_saveFileMan;
+
 #define SAVEGAME_HEADERTAG	'RSAV'
 #define SAVEGAME_FOOTERTAG	'ESAV'
 #define SAVEGAME_VERSION		2

Modified: residual/trunk/engine/savegame.h
===================================================================
--- residual/trunk/engine/savegame.h	2008-07-20 14:30:25 UTC (rev 33127)
+++ residual/trunk/engine/savegame.h	2008-07-20 15:00:50 UTC (rev 33128)
@@ -36,6 +36,12 @@
 
 #include "engine/lua.h"
 
+namespace Common {
+	class SaveFileManager;
+}
+
+extern Common::SaveFileManager *g_saveFileMan;
+
 class SaveGame {
 public:
 	SaveGame(const char *filename, bool saving);


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