diff options
Diffstat (limited to 'engines/gob/saveload_v2.cpp')
-rw-r--r-- | engines/gob/saveload_v2.cpp | 286 |
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 |