[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