aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/saveload_v2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/saveload_v2.cpp')
-rw-r--r--engines/gob/saveload_v2.cpp286
1 files changed, 286 insertions, 0 deletions
diff --git a/engines/gob/saveload_v2.cpp b/engines/gob/saveload_v2.cpp
new file mode 100644
index 0000000000..b8aa0ec804
--- /dev/null
+++ b/engines/gob/saveload_v2.cpp
@@ -0,0 +1,286 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 Ivan Dubrov
+ * Copyright (C) 2004-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "common/endian.h"
+#include "common/file.h"
+
+#include "gob/gob.h"
+#include "gob/saveload.h"
+#include "gob/global.h"
+#include "gob/game.h"
+
+namespace Gob {
+
+SaveLoad_v2::SaveLoad_v2(GobEngine *vm, const char *targetName) :
+ SaveLoad(vm, targetName) {
+
+ _stagesCount = 1;
+
+ _buffer = new byte*[_stagesCount];
+
+ assert(_buffer);
+
+ _buffer[0] = 0;
+}
+
+SaveType SaveLoad_v2::getSaveType(const char *fileName) {
+ if (!scumm_stricmp(fileName, "cat.inf"))
+ return kSaveGame;
+ if (!scumm_stricmp(fileName, "cat.cat"))
+ return kSaveGame;
+ if (!scumm_stricmp(fileName, "save.inf"))
+ return kSaveTempSprite;
+ if (!scumm_stricmp(fileName, "bloc.inf"))
+ return kSaveNotes;
+
+ return kSaveNone;
+}
+
+uint32 SaveLoad_v2::getSaveGameSize() {
+ return 80 + (READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4) * 2;
+}
+
+int32 SaveLoad_v2::getSizeNotes() {
+ Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+ Common::InSaveFile *in;
+ int32 size = -1;
+
+ in = saveMan->openForLoading(_saveFiles[(int) kSaveNotes]);
+ if (in) {
+ size = in->size();
+ delete in;
+ }
+
+ return size;
+}
+
+int32 SaveLoad_v2::getSizeGame() {
+ Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+ Common::InSaveFile *in;
+
+ for (int i = 14; i >= 0; i--) {
+ in = saveMan->openForLoading(setCurSlot(i));
+ if (in) {
+ delete in;
+ return (i + 1) * READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) *
+ 4 + 600;
+ }
+ }
+
+ return -1;
+}
+
+int32 SaveLoad_v2::getSizeScreenshot() {
+ return -1;
+}
+
+bool SaveLoad_v2::loadGame(int16 dataVar, int32 size, int32 offset) {
+ Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+ Common::InSaveFile *in;
+ int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+
+ if (size == 0) {
+ dataVar = 0;
+ size = varSize;
+ }
+
+ int slot = (offset - 600) / varSize;
+ int slotR = (offset - 600) % varSize;
+
+ if ((offset == 0) && (size == 600)) {
+
+ byte *varBuf = _vm->_global->_inter_variables + dataVar;
+ for (int i = 0; i < 15; i++, varBuf += 40) {
+ in = saveMan->openForLoading(setCurSlot(i));
+ if (in) {
+ in->read(varBuf, 40);
+ delete in;
+ } else
+ memset(varBuf, 0, 40);
+ }
+ memset(_vm->_global->_inter_variablesSizes + dataVar, 0, 600);
+ return true;
+
+ } else if ((offset > 0) && (slot < 15) &&
+ (slotR == 0) && (size == varSize)) {
+
+ in = saveMan->openForLoading(setCurSlot(slot));
+ if (!in) {
+ warning("Can't open file for slot %d", slot);
+ return false;
+ }
+
+ uint32 sGameSize = getSaveGameSize();
+ uint32 fSize = in->size();
+ if (fSize != sGameSize) {
+ warning("Can't load from slot %d: Wrong size (%d, %d)", slot,
+ fSize, sGameSize);
+ delete in;
+ return false;
+ }
+
+ in->seek(80);
+ if (loadDataEndian(*in, dataVar, size)) {
+ delete in;
+ debugC(1, kDebugFileIO, "Loading from slot %d", slot);
+ return true;
+ }
+ delete in;
+
+ } else
+ warning("Invalid loading procedure (%d, %d, %d, %d)",
+ offset, size, slot, slotR);
+
+ return false;
+}
+
+bool SaveLoad_v2::loadNotes(int16 dataVar, int32 size, int32 offset) {
+ bool retVal;
+
+ if ((size <= 0) || (offset != 0)) {
+ warning("Invalid attempt at loading the notes (%d, %d)", size, offset);
+ return false;
+ }
+
+ Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+ char *sName = _saveFiles[(int) kSaveNotes];
+
+ Common::InSaveFile *in = saveMan->openForLoading(sName);
+ if (!in) {
+ warning("Can't open file \"%s\" for reading", sName);
+ return false;
+ }
+
+ retVal = loadDataEndian(*in, dataVar, size);
+ delete in;
+ return retVal;
+}
+
+bool SaveLoad_v2::loadScreenshot(int16 dataVar, int32 size, int32 offset) {
+ return false;
+}
+
+bool SaveLoad_v2::saveGame(int16 dataVar, int32 size, int32 offset) {
+ int32 varSize = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+
+ if (size == 0) {
+ dataVar = 0;
+ size = varSize;
+ }
+
+ int slot = (offset - 600) / varSize;
+ int slotR = (offset - 600) % varSize;
+
+ if ((offset == 0) && (size == 600)) {
+
+ delete[] _buffer[0];
+ _buffer[0] = new byte[1200];
+ assert(_buffer[0]);
+
+ memcpy(_buffer[0], _vm->_global->_inter_variables + dataVar, 600);
+ memset(_buffer[0] + 600, 0, 600);
+
+ return true;
+
+ } else if ((offset > 0) && (slot < 15) &&
+ (slotR == 0) && (size == varSize)) {
+
+ if (!_buffer[0]) {
+ warning("Tried to save without writing the index first");
+ return false;
+ }
+
+ Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+ Common::OutSaveFile *out;
+
+ out = saveMan->openForSaving(setCurSlot(slot));
+ if (!out) {
+ warning("Can't open file for slot %d for writing", slot);
+ delete[] _buffer[0];
+ _buffer[0] = 0;
+ return false;
+ }
+
+ bool retVal = false;
+
+ if (out->write(_buffer[0] + slot * 40, 40) == 40)
+ if (out->write(_buffer[0] + 600 + slot * 40, 40) == 40)
+ if (saveDataEndian(*out, dataVar, size)) {
+ out->finalize();
+ if (!out->ioFailed())
+ retVal = true;
+ }
+
+ if (!retVal)
+ warning("Can't save to slot %d", slot);
+ else
+ debugC(1, kDebugFileIO, "Saved to slot %d", slot);
+
+ delete[] _buffer[0];
+ _buffer[0] = 0;
+ delete out;
+
+ return retVal;
+
+ } else
+ warning("Invalid saving procedure (%d, %d, %d, %d)",
+ offset, size, slot, slotR);
+
+ return false;
+}
+
+bool SaveLoad_v2::saveNotes(int16 dataVar, int32 size, int32 offset) {
+ bool retVal;
+
+ if ((size <= 0) || (offset != 0)) {
+ warning("Invalid attempt at saving the notes (%d, %d)", size, offset);
+ return false;
+ }
+
+ Common::SaveFileManager *saveMan = g_system->getSavefileManager();
+ char *sName = _saveFiles[(int) kSaveNotes];
+
+ Common::OutSaveFile *out = saveMan->openForSaving(sName);
+ if (!out) {
+ warning("Can't open file \"%s\" for writing", sName);
+ return false;
+ }
+
+ retVal = saveDataEndian(*out, dataVar, size);
+
+ out->finalize();
+ if (out->ioFailed()) {
+ warning("Can't save notes");
+ retVal = false;
+ }
+
+ delete out;
+ return retVal;
+}
+
+bool SaveLoad_v2::saveScreenshot(int16 dataVar, int32 size, int32 offset) {
+ return false;
+}
+
+} // End of namespace Gob