2012-03-05 23:29:08 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* 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.
|
2012-05-11 14:03:59 +00:00
|
|
|
|
2012-03-05 23:29:08 +00:00
|
|
|
* 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.
|
2012-05-11 14:03:59 +00:00
|
|
|
|
2012-03-05 23:29:08 +00:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is based on WME Lite.
|
|
|
|
* http://dead-code.org/redir.php?target=wmelite
|
|
|
|
* Copyright (c) 2011 Jan Nedoma
|
|
|
|
*/
|
|
|
|
|
2012-06-02 00:05:11 +00:00
|
|
|
#include "engines/wintermute/dcgf.h"
|
|
|
|
#include "engines/wintermute/Base/BFileManager.h"
|
|
|
|
#include "engines/wintermute/Base/BGame.h"
|
|
|
|
#include "engines/wintermute/Base/BPersistMgr.h"
|
|
|
|
#include "engines/wintermute/Base/BSaveThumbHelper.h"
|
|
|
|
#include "engines/wintermute/PlatformSDL.h"
|
2012-06-02 00:21:01 +00:00
|
|
|
#include "engines/wintermute/math/Vector2.h"
|
2012-06-02 00:31:59 +00:00
|
|
|
#include "engines/wintermute/utils/StringUtil.h"
|
2012-06-02 00:05:11 +00:00
|
|
|
#include "engines/wintermute/Base/BImage.h"
|
|
|
|
#include "engines/wintermute/Base/BSound.h"
|
2012-06-19 00:02:20 +00:00
|
|
|
#include "graphics/decoders/bmp.h"
|
|
|
|
#include "common/memstream.h"
|
2012-03-05 23:29:08 +00:00
|
|
|
#include "common/str.h"
|
2012-06-19 00:02:20 +00:00
|
|
|
#include "common/system.h"
|
|
|
|
#include "common/savefile.h"
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
namespace WinterMute {
|
|
|
|
|
|
|
|
#define SAVE_BUFFER_INIT_SIZE 100000
|
|
|
|
#define SAVE_BUFFER_GROW_BY 50000
|
|
|
|
|
|
|
|
#define SAVE_MAGIC 0x45564153
|
|
|
|
#define SAVE_MAGIC_2 0x32564153
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
CBPersistMgr::CBPersistMgr(CBGame *inGame): CBBase(inGame) {
|
2012-04-27 22:00:14 +00:00
|
|
|
_saving = false;
|
2012-06-16 00:14:35 +00:00
|
|
|
// _buffer = NULL;
|
|
|
|
// _bufferSize = 0;
|
2012-04-27 22:00:14 +00:00
|
|
|
_offset = 0;
|
2012-06-16 00:14:35 +00:00
|
|
|
_saveStream = NULL;
|
|
|
|
_loadStream = NULL;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
_richBuffer = NULL;
|
|
|
|
_richBufferSize = 0;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
_savedDescription = NULL;
|
2012-06-19 00:02:20 +00:00
|
|
|
// _savedTimestamp = 0;
|
2012-04-27 22:00:14 +00:00
|
|
|
_savedVerMajor = _savedVerMinor = _savedVerBuild = 0;
|
|
|
|
_savedExtMajor = _savedExtMinor = 0;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
_thumbnailDataSize = 0;
|
|
|
|
_thumbnailData = NULL;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
CBPersistMgr::~CBPersistMgr() {
|
2012-06-22 11:56:51 +00:00
|
|
|
cleanup();
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
void CBPersistMgr::cleanup() {
|
|
|
|
/* if (_buffer) {
|
|
|
|
if (_saving) free(_buffer);
|
|
|
|
else delete [] _buffer; // allocated by file manager
|
|
|
|
}
|
|
|
|
_buffer = NULL;
|
|
|
|
|
|
|
|
_bufferSize = 0;*/
|
2012-04-27 22:00:14 +00:00
|
|
|
_offset = 0;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
delete[] _richBuffer;
|
|
|
|
_richBuffer = NULL;
|
|
|
|
_richBufferSize = 0;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
_savedDescription = NULL; // ref to buffer
|
2012-06-19 00:02:20 +00:00
|
|
|
// _savedTimestamp = 0;
|
2012-04-27 22:00:14 +00:00
|
|
|
_savedVerMajor = _savedVerMinor = _savedVerBuild = 0;
|
|
|
|
_savedExtMajor = _savedExtMinor = 0;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
_thumbnailDataSize = 0;
|
|
|
|
if (_thumbnailData) {
|
|
|
|
delete [] _thumbnailData;
|
|
|
|
_thumbnailData = NULL;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
2012-06-22 11:56:51 +00:00
|
|
|
|
2012-06-16 00:14:35 +00:00
|
|
|
delete _loadStream;
|
|
|
|
delete _saveStream;
|
|
|
|
_loadStream = NULL;
|
|
|
|
_saveStream = NULL;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
Common::String CBPersistMgr::getFilenameForSlot(int slot) {
|
|
|
|
// TODO: Temporary solution until I have the namespacing sorted out
|
|
|
|
return Common::String::format("save%03d.DirtySplitSav", slot);
|
|
|
|
}
|
|
|
|
|
2012-06-22 11:56:51 +00:00
|
|
|
void CBPersistMgr::getSaveStateDesc(int slot, SaveStateDescriptor &desc) {
|
2012-06-19 00:02:20 +00:00
|
|
|
Common::String filename = getFilenameForSlot(slot);
|
|
|
|
warning("Trying to list savegame %s in slot %d", filename.c_str(), slot);
|
|
|
|
if (FAILED(readHeader(filename))) {
|
|
|
|
warning("getSavedDesc(%d) - Failed for %s", slot, filename.c_str());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
desc.setSaveSlot(slot);
|
|
|
|
desc.setDescription(_savedDescription);
|
|
|
|
desc.setDeletableFlag(true);
|
|
|
|
desc.setWriteProtectedFlag(false);
|
2012-06-22 11:56:51 +00:00
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
if (_thumbnailDataSize > 0) {
|
|
|
|
Common::MemoryReadStream thumbStream(_thumbnailData, _thumbnailDataSize);
|
|
|
|
Graphics::BitmapDecoder bmpDecoder;
|
|
|
|
if (bmpDecoder.loadStream(thumbStream)) {
|
|
|
|
Graphics::Surface *surf = new Graphics::Surface;
|
|
|
|
surf = bmpDecoder.getSurface()->convertTo(g_system->getOverlayFormat());
|
|
|
|
desc.setThumbnail(surf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
desc.setSaveDate(_savedTimestamp.tm_year, _savedTimestamp.tm_mon, _savedTimestamp.tm_mday);
|
|
|
|
desc.setSaveTime(_savedTimestamp.tm_hour, _savedTimestamp.tm_min);
|
|
|
|
desc.setPlayTime(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CBPersistMgr::deleteSaveSlot(int slot) {
|
|
|
|
Common::String filename = getFilenameForSlot(slot);
|
|
|
|
g_system->getSavefileManager()->removeSavefile(filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CBPersistMgr::getMaxUsedSlot() {
|
|
|
|
Common::StringArray saves = g_system->getSavefileManager()->listSavefiles("save???.DirtySplitSav");
|
|
|
|
Common::StringArray::iterator it = saves.begin();
|
|
|
|
int ret = -1;
|
|
|
|
for (; it != saves.end(); it++) {
|
|
|
|
int num = -1;
|
|
|
|
sscanf(it->c_str(), "save%d", &num);
|
|
|
|
ret = MAX(ret, num);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CBPersistMgr::getSaveExists(int slot) {
|
|
|
|
Common::String filename = getFilenameForSlot(slot);
|
|
|
|
warning("Trying to list savegame %s in slot %d", filename.c_str(), slot);
|
|
|
|
if (FAILED(readHeader(filename))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-03-05 23:29:08 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::initSave(const char *desc) {
|
|
|
|
if (!desc) return E_FAIL;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-22 11:56:51 +00:00
|
|
|
cleanup();
|
2012-04-27 22:00:14 +00:00
|
|
|
_saving = true;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-16 00:14:35 +00:00
|
|
|
_saveStream = new Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saveStream) {
|
2012-03-05 23:29:08 +00:00
|
|
|
// get thumbnails
|
2012-04-27 22:00:14 +00:00
|
|
|
if (!Game->_cachedThumbnail) {
|
|
|
|
Game->_cachedThumbnail = new CBSaveThumbHelper(Game);
|
|
|
|
if (FAILED(Game->_cachedThumbnail->StoreThumbnail(true))) {
|
|
|
|
delete Game->_cachedThumbnail;
|
|
|
|
Game->_cachedThumbnail = NULL;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 magic = DCGF_MAGIC;
|
2012-06-22 11:56:51 +00:00
|
|
|
putDWORD(magic);
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
magic = SAVE_MAGIC_2;
|
2012-06-22 11:56:51 +00:00
|
|
|
putDWORD(magic);
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
byte VerMajor, VerMinor, ExtMajor, ExtMinor;
|
|
|
|
Game->GetVersion(&VerMajor, &VerMinor, &ExtMajor, &ExtMinor);
|
|
|
|
//uint32 Version = MAKELONG(MAKEWORD(VerMajor, VerMinor), MAKEWORD(ExtMajor, ExtMinor));
|
2012-06-16 00:14:35 +00:00
|
|
|
_saveStream->writeByte(VerMajor);
|
|
|
|
_saveStream->writeByte(VerMinor);
|
|
|
|
_saveStream->writeByte(ExtMajor);
|
|
|
|
_saveStream->writeByte(ExtMinor);
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
// new in ver 2
|
2012-06-22 11:56:51 +00:00
|
|
|
putDWORD((uint32)DCGF_VER_BUILD);
|
|
|
|
putString(Game->_name);
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
// thumbnail data size
|
2012-06-22 18:06:12 +00:00
|
|
|
bool thumbnailOK = false;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
if (Game->_cachedThumbnail) {
|
|
|
|
if (Game->_cachedThumbnail->_thumbnail) {
|
2012-06-18 17:11:15 +00:00
|
|
|
Common::MemoryWriteStreamDynamic thumbStream(DisposeAfterUse::YES);
|
|
|
|
if (Game->_cachedThumbnail->_thumbnail->writeBMPToStream(&thumbStream)) {
|
|
|
|
_saveStream->writeUint32LE(thumbStream.size());
|
|
|
|
_saveStream->write(thumbStream.getData(), thumbStream.size());
|
|
|
|
} else {
|
|
|
|
_saveStream->writeUint32LE(0);
|
|
|
|
}
|
|
|
|
|
2012-06-22 18:06:12 +00:00
|
|
|
thumbnailOK = true;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
}
|
2012-06-22 18:06:12 +00:00
|
|
|
if (!thumbnailOK) putDWORD(0);
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
// in any case, destroy the cached thumbnail once used
|
2012-04-27 22:00:14 +00:00
|
|
|
delete Game->_cachedThumbnail;
|
|
|
|
Game->_cachedThumbnail = NULL;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-22 11:56:51 +00:00
|
|
|
uint32 dataOffset = _offset +
|
2012-05-11 14:03:59 +00:00
|
|
|
sizeof(uint32) + // data offset
|
2012-06-22 11:56:51 +00:00
|
|
|
sizeof(uint32) + strlen(desc) + 1 + // description
|
2012-05-11 14:03:59 +00:00
|
|
|
sizeof(uint32); // timestamp
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-22 11:56:51 +00:00
|
|
|
putDWORD(dataOffset);
|
|
|
|
putString(desc);
|
2012-06-19 00:02:20 +00:00
|
|
|
|
|
|
|
g_system->getTimeAndDate(_savedTimestamp);
|
|
|
|
putTimeDate(_savedTimestamp);
|
|
|
|
_savedPlayTime = g_system->getMillis();
|
|
|
|
_saveStream->writeUint32LE(_savedPlayTime);
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
2012-06-16 00:14:35 +00:00
|
|
|
return S_OK;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
HRESULT CBPersistMgr::readHeader(const Common::String &filename) {
|
2012-06-22 11:56:51 +00:00
|
|
|
cleanup();
|
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
_saving = false;
|
2012-06-22 11:56:51 +00:00
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
_loadStream = g_system->getSavefileManager()->openForLoading(filename);
|
2012-06-26 00:07:12 +00:00
|
|
|
//_buffer = Game->_fileManager->readWholeFile(Filename, &_bufferSize);
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream) {
|
2012-03-05 23:29:08 +00:00
|
|
|
uint32 Magic;
|
2012-06-22 11:56:51 +00:00
|
|
|
Magic = getDWORD();
|
2012-06-19 00:02:20 +00:00
|
|
|
|
|
|
|
if (Magic != DCGF_MAGIC) {
|
2012-06-22 11:56:51 +00:00
|
|
|
cleanup();
|
2012-06-19 00:02:20 +00:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-22 11:56:51 +00:00
|
|
|
Magic = getDWORD();
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
if (Magic == SAVE_MAGIC || Magic == SAVE_MAGIC_2) {
|
2012-06-16 00:14:35 +00:00
|
|
|
_savedVerMajor = _loadStream->readByte();
|
|
|
|
_savedVerMinor = _loadStream->readByte();
|
|
|
|
_savedExtMajor = _loadStream->readByte();
|
|
|
|
_savedExtMinor = _loadStream->readByte();
|
2012-06-22 11:56:51 +00:00
|
|
|
|
2012-03-05 23:29:08 +00:00
|
|
|
if (Magic == SAVE_MAGIC_2) {
|
2012-06-22 11:56:51 +00:00
|
|
|
_savedVerBuild = (byte)getDWORD();
|
|
|
|
_savedName = getString();
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
// load thumbnail
|
2012-06-22 11:56:51 +00:00
|
|
|
_thumbnailDataSize = getDWORD();
|
2012-04-27 22:00:14 +00:00
|
|
|
if (_thumbnailDataSize > 0) {
|
|
|
|
_thumbnailData = new byte[_thumbnailDataSize];
|
|
|
|
if (_thumbnailData) {
|
2012-06-22 11:56:51 +00:00
|
|
|
getBytes(_thumbnailData, _thumbnailDataSize);
|
2012-04-27 22:00:14 +00:00
|
|
|
} else _thumbnailDataSize = 0;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
2012-04-27 22:00:14 +00:00
|
|
|
} else _savedVerBuild = 35; // last build with ver1 savegames
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-22 18:06:12 +00:00
|
|
|
uint32 dataOffset = getDWORD();
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-22 11:56:51 +00:00
|
|
|
_savedDescription = getString();
|
2012-06-19 00:02:20 +00:00
|
|
|
_savedTimestamp = getTimeDate();
|
|
|
|
_savedPlayTime = _loadStream->readUint32LE();
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-22 18:06:12 +00:00
|
|
|
_offset = dataOffset;
|
2012-06-22 11:56:51 +00:00
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-22 11:56:51 +00:00
|
|
|
cleanup();
|
2012-06-19 00:02:20 +00:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::initLoad(const char *filename) {
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
|
2012-06-22 11:56:51 +00:00
|
|
|
if (FAILED(readHeader(filename))) {
|
|
|
|
cleanup();
|
2012-06-19 00:02:20 +00:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
_saving = false;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
if (_savedName == "" || scumm_stricmp(_savedName.c_str(), Game->_name) != 0) {
|
|
|
|
Game->LOG(0, "ERROR: Saved game name doesn't match current game");
|
2012-06-22 11:56:51 +00:00
|
|
|
cleanup();
|
2012-06-19 00:02:20 +00:00
|
|
|
return E_FAIL;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
// if save is newer version than we are, fail
|
|
|
|
if (_savedVerMajor > DCGF_VER_MAJOR ||
|
2012-06-22 11:56:51 +00:00
|
|
|
(_savedVerMajor == DCGF_VER_MAJOR && _savedVerMinor > DCGF_VER_MINOR) ||
|
|
|
|
(_savedVerMajor == DCGF_VER_MAJOR && _savedVerMinor == DCGF_VER_MINOR && _savedVerBuild > DCGF_VER_BUILD)
|
|
|
|
) {
|
2012-06-19 00:02:20 +00:00
|
|
|
Game->LOG(0, "ERROR: Saved game version is newer than current game");
|
2012-06-27 13:15:46 +00:00
|
|
|
Game->LOG(0, "ERROR: Expected %d.%d.%d got %d.%d.%d", DCGF_VER_MAJOR, DCGF_VER_MINOR, DCGF_VER_BUILD, _savedVerMajor, _savedVerMinor, _savedVerBuild);
|
2012-06-22 11:56:51 +00:00
|
|
|
cleanup();
|
2012-06-19 00:02:20 +00:00
|
|
|
return E_FAIL;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
// if save is older than the minimal version we support
|
|
|
|
if (_savedVerMajor < SAVEGAME_VER_MAJOR ||
|
2012-06-22 11:56:51 +00:00
|
|
|
(_savedVerMajor == SAVEGAME_VER_MAJOR && _savedVerMinor < SAVEGAME_VER_MINOR) ||
|
|
|
|
(_savedVerMajor == SAVEGAME_VER_MAJOR && _savedVerMinor == SAVEGAME_VER_MINOR && _savedVerBuild < SAVEGAME_VER_BUILD)
|
|
|
|
) {
|
2012-06-19 00:02:20 +00:00
|
|
|
Game->LOG(0, "ERROR: Saved game is too old and cannot be used by this version of game engine");
|
2012-06-27 13:15:46 +00:00
|
|
|
Game->LOG(0, "ERROR: Expected %d.%d.%d got %d.%d.%d", DCGF_VER_MAJOR, DCGF_VER_MINOR, DCGF_VER_BUILD, _savedVerMajor, _savedVerMinor, _savedVerBuild);
|
2012-06-22 11:56:51 +00:00
|
|
|
cleanup();
|
2012-06-19 00:02:20 +00:00
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
if ( _savedVerMajor != DCGF_VER_MAJOR || _savedVerMinor != DCGF_VER_MINOR)
|
|
|
|
{
|
|
|
|
Game->LOG(0, "ERROR: Saved game is created by other WME version");
|
|
|
|
goto init_fail;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
return S_OK;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::saveFile(const char *filename) {
|
2012-06-26 00:07:12 +00:00
|
|
|
return Game->_fileManager->saveFile(filename, ((Common::MemoryWriteStreamDynamic *)_saveStream)->getData(), ((Common::MemoryWriteStreamDynamic *)_saveStream)->size(), Game->_compressedSavegames, _richBuffer, _richBufferSize);
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::putBytes(byte *buffer, uint32 size) {
|
2012-06-16 00:14:35 +00:00
|
|
|
_saveStream->write(buffer, size);
|
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::getBytes(byte *buffer, uint32 size) {
|
2012-06-16 00:14:35 +00:00
|
|
|
_loadStream->read(buffer, size);
|
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
void CBPersistMgr::putDWORD(uint32 val) {
|
|
|
|
_saveStream->writeUint32LE(val);
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
uint32 CBPersistMgr::getDWORD() {
|
2012-06-16 00:14:35 +00:00
|
|
|
uint32 ret = _loadStream->readUint32LE();
|
2012-03-05 23:29:08 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
void CBPersistMgr::putString(const Common::String &val) {
|
|
|
|
if (!val.size()) putString("(null)");
|
2012-03-05 23:29:08 +00:00
|
|
|
else {
|
2012-06-22 11:56:51 +00:00
|
|
|
_saveStream->writeUint32LE(val.size());
|
|
|
|
_saveStream->writeString(val);
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
char *CBPersistMgr::getString() {
|
2012-06-16 00:14:35 +00:00
|
|
|
uint32 len = _loadStream->readUint32LE();
|
|
|
|
char *ret = new char[len + 1];
|
|
|
|
_loadStream->read(ret, len);
|
|
|
|
ret[len] = '\0';
|
2012-06-22 11:56:51 +00:00
|
|
|
|
|
|
|
if (!strcmp(ret, "(null)")) {
|
2012-06-16 00:14:35 +00:00
|
|
|
delete[] ret;
|
|
|
|
return NULL;
|
|
|
|
} else return ret;
|
|
|
|
}
|
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
HRESULT CBPersistMgr::putTimeDate(const TimeDate &t) {
|
|
|
|
_saveStream->writeSint32LE(t.tm_sec);
|
|
|
|
_saveStream->writeSint32LE(t.tm_min);
|
|
|
|
_saveStream->writeSint32LE(t.tm_hour);
|
|
|
|
_saveStream->writeSint32LE(t.tm_mday);
|
|
|
|
_saveStream->writeSint32LE(t.tm_mon);
|
|
|
|
_saveStream->writeSint32LE(t.tm_year);
|
|
|
|
// _saveStream->writeSint32LE(t.tm_wday); //TODO: Add this in when merging next
|
2012-06-22 11:56:51 +00:00
|
|
|
|
2012-06-19 00:02:20 +00:00
|
|
|
if (_saveStream->err()) {
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
TimeDate CBPersistMgr::getTimeDate() {
|
|
|
|
TimeDate t;
|
|
|
|
t.tm_sec = _loadStream->readSint32LE();
|
|
|
|
t.tm_min = _loadStream->readSint32LE();
|
|
|
|
t.tm_hour = _loadStream->readSint32LE();
|
|
|
|
t.tm_mday = _loadStream->readSint32LE();
|
|
|
|
t.tm_mon = _loadStream->readSint32LE();
|
|
|
|
t.tm_year = _loadStream->readSint32LE();
|
|
|
|
// t.tm_wday = _loadStream->readSint32LE(); //TODO: Add this in when merging next
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2012-06-16 00:14:35 +00:00
|
|
|
void CBPersistMgr::putFloat(float val) {
|
|
|
|
Common::String str = Common::String::format("F%f", val);
|
|
|
|
_saveStream->writeUint32LE(str.size());
|
|
|
|
_saveStream->writeString(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
float CBPersistMgr::getFloat() {
|
2012-06-22 11:56:51 +00:00
|
|
|
char *str = getString();
|
2012-06-16 00:14:35 +00:00
|
|
|
float value = 0.0f;
|
|
|
|
int ret = sscanf(str, "F%f", &value);
|
|
|
|
if (ret != 1) {
|
|
|
|
warning("%s not parsed as float", str);
|
|
|
|
}
|
|
|
|
delete[] str;
|
|
|
|
return value;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-16 00:14:35 +00:00
|
|
|
void CBPersistMgr::putDouble(double val) {
|
|
|
|
Common::String str = Common::String::format("F%f", val);
|
|
|
|
str.format("D%f", val);
|
|
|
|
_saveStream->writeUint32LE(str.size());
|
|
|
|
_saveStream->writeString(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
double CBPersistMgr::getDouble() {
|
2012-06-22 11:56:51 +00:00
|
|
|
char *str = getString();
|
2012-06-16 00:14:35 +00:00
|
|
|
double value = 0.0f;
|
|
|
|
int ret = sscanf(str, "F%f", &value);
|
|
|
|
if (ret != 1) {
|
|
|
|
warning("%s not parsed as float", str);
|
|
|
|
}
|
|
|
|
delete[] str;
|
|
|
|
return value;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// bool
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, bool *val) {
|
|
|
|
if (_saving) {
|
|
|
|
_saveStream->writeByte(*val);
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
*val = _loadStream->readByte();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// int
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, int *val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
_saveStream->writeSint32LE(*val);
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
*val = _loadStream->readSint32LE();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// DWORD
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, uint32 *val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
_saveStream->writeUint32LE(*val);
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
*val = _loadStream->readUint32LE();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// float
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, float *val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
putFloat(*val);
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
*val = getFloat();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// double
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, double *val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
putDouble(*val);
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
*val = getDouble();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// char*
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, char **val) {
|
2012-04-27 22:00:14 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
putString(*val);
|
2012-03-05 23:29:08 +00:00
|
|
|
return S_OK;
|
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
char *str = getString();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err()) {
|
|
|
|
delete[] str;
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
2012-06-22 11:56:51 +00:00
|
|
|
*val = str;
|
2012-06-16 00:14:35 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-16 00:14:35 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// const char*
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, const char **val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
putString(*val);
|
2012-06-16 00:14:35 +00:00
|
|
|
return S_OK;
|
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
char *str = getString();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err()) {
|
|
|
|
delete[] str;
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
2012-06-22 11:56:51 +00:00
|
|
|
*val = str;
|
2012-06-16 00:14:35 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Common::String
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, Common::String *val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
putString(*val);
|
2012-06-16 00:14:35 +00:00
|
|
|
return S_OK;
|
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
char *str = getString();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err()) {
|
|
|
|
delete[] str;
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
2012-06-16 14:53:33 +00:00
|
|
|
if (str) {
|
|
|
|
*val = str;
|
|
|
|
delete[] str;
|
|
|
|
} else {
|
|
|
|
*val = "";
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, AnsiStringArray &val) {
|
2012-03-05 23:29:08 +00:00
|
|
|
size_t size;
|
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
size = val.size();
|
2012-06-16 00:14:35 +00:00
|
|
|
_saveStream->writeUint32LE(size);
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-22 11:56:51 +00:00
|
|
|
for (AnsiStringArray::iterator it = val.begin(); it != val.end(); ++it) {
|
|
|
|
putString((*it).c_str());
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
val.clear();
|
2012-06-16 00:14:35 +00:00
|
|
|
size = _loadStream->readUint32LE();
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
for (size_t i = 0; i < size; i++) {
|
2012-06-22 11:56:51 +00:00
|
|
|
char *str = getString();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err()) {
|
|
|
|
delete[] str;
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
2012-06-22 11:56:51 +00:00
|
|
|
if (str) val.push_back(str);
|
2012-06-16 00:14:35 +00:00
|
|
|
delete[] str;
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// BYTE
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, byte *val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
_saveStream->writeByte(*val);
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
2012-06-22 11:56:51 +00:00
|
|
|
} else {
|
|
|
|
*val = _loadStream->readByte();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// RECT
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, RECT *val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
_saveStream->writeSint32LE(val->left);
|
|
|
|
_saveStream->writeSint32LE(val->top);
|
|
|
|
_saveStream->writeSint32LE(val->right);
|
|
|
|
_saveStream->writeSint32LE(val->bottom);
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
2012-06-22 11:56:51 +00:00
|
|
|
} else {
|
|
|
|
val->left = _loadStream->readSint32LE();
|
|
|
|
val->top = _loadStream->readSint32LE();
|
|
|
|
val->right = _loadStream->readSint32LE();
|
|
|
|
val->bottom = _loadStream->readSint32LE();
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// POINT
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, POINT *val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
_saveStream->writeSint32LE(val->x);
|
|
|
|
_saveStream->writeSint32LE(val->y);
|
2012-06-22 11:59:28 +00:00
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
2012-06-16 00:14:35 +00:00
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
val->x = _loadStream->readSint32LE();
|
|
|
|
val->y = _loadStream->readSint32LE();
|
2012-06-22 11:59:28 +00:00
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
2012-06-16 00:14:35 +00:00
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Vector2
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, Vector2 *val) {
|
2012-06-16 00:14:35 +00:00
|
|
|
if (_saving) {
|
2012-06-22 11:56:51 +00:00
|
|
|
putFloat(val->x);
|
|
|
|
putFloat(val->y);
|
2012-06-22 11:59:28 +00:00
|
|
|
if (_saveStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
2012-06-16 00:14:35 +00:00
|
|
|
} else {
|
2012-06-22 11:56:51 +00:00
|
|
|
val->x = getFloat();
|
|
|
|
val->y = getFloat();
|
2012-06-22 11:59:28 +00:00
|
|
|
if (_loadStream->err())
|
|
|
|
return E_FAIL;
|
|
|
|
return S_OK;
|
2012-06-16 00:14:35 +00:00
|
|
|
}
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// generic pointer
|
2012-06-22 11:56:51 +00:00
|
|
|
HRESULT CBPersistMgr::transfer(const char *name, void *val) {
|
2012-03-05 23:29:08 +00:00
|
|
|
int ClassID = -1, InstanceID = -1;
|
|
|
|
|
2012-04-27 22:00:14 +00:00
|
|
|
if (_saving) {
|
2012-06-26 12:28:53 +00:00
|
|
|
CSysClassRegistry::getInstance()->getPointerID(*(void **)val, &ClassID, &InstanceID);
|
2012-06-22 11:56:51 +00:00
|
|
|
if (*(void **)val != NULL && (ClassID == -1 || InstanceID == -1)) {
|
|
|
|
Game->LOG(0, "Warning: invalid instance '%s'", name);
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
2012-06-16 00:14:35 +00:00
|
|
|
_saveStream->writeUint32LE(ClassID);
|
|
|
|
_saveStream->writeUint32LE(InstanceID);
|
2012-03-05 23:29:08 +00:00
|
|
|
} else {
|
2012-06-16 00:14:35 +00:00
|
|
|
ClassID = _loadStream->readUint32LE();
|
|
|
|
InstanceID = _loadStream->readUint32LE();
|
2012-03-05 23:29:08 +00:00
|
|
|
|
2012-06-26 12:28:53 +00:00
|
|
|
*(void **)val = CSysClassRegistry::getInstance()->idToPointer(ClassID, InstanceID);
|
2012-03-05 23:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2012-06-22 11:56:51 +00:00
|
|
|
bool CBPersistMgr::checkVersion(byte verMajor, byte verMinor, byte verBuild) {
|
2012-04-27 22:00:14 +00:00
|
|
|
if (_saving) return true;
|
2012-03-05 23:29:08 +00:00
|
|
|
|
|
|
|
// it's ok if we are same or newer than the saved game
|
2012-06-22 11:56:51 +00:00
|
|
|
if (verMajor > _savedVerMajor ||
|
|
|
|
(verMajor == _savedVerMajor && verMinor > _savedVerMinor) ||
|
|
|
|
(verMajor == _savedVerMajor && verMinor == _savedVerMinor && verBuild > _savedVerBuild)
|
2012-03-05 23:29:08 +00:00
|
|
|
) return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end of namespace WinterMute
|