From 4ceecdb25fde5e82f4e96774ebfb28d5d319820c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 18 Dec 2008 02:48:15 +0000 Subject: Preliminary save/load support for Urban Runner svn-id: r35418 --- engines/gob/saveload_v6.cpp | 244 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 2 deletions(-) (limited to 'engines/gob/saveload_v6.cpp') diff --git a/engines/gob/saveload_v6.cpp b/engines/gob/saveload_v6.cpp index cc233a36ba..b3e9eec2c1 100644 --- a/engines/gob/saveload_v6.cpp +++ b/engines/gob/saveload_v6.cpp @@ -28,19 +28,35 @@ #include "gob/gob.h" #include "gob/saveload.h" #include "gob/game.h" +#include "gob/inter.h" namespace Gob { SaveLoad_v6::SaveFile SaveLoad_v6::_saveFiles[] = { - {"mdo.def", 0, kSaveModeExists, kSaveNone}, - {"NO_CD.TXT", 0, kSaveModeExists, kSaveNoCD} + { "cat.inf", 0, kSaveModeSave, kSaveGame}, + { "mdo.def", 0, kSaveModeExists, kSaveNone}, + {"no_cd.txt", 0, kSaveModeExists, kSaveNoCD}, }; SaveLoad_v6::SaveLoad_v6(GobEngine *vm, const char *targetName) : SaveLoad(vm, targetName) { + + _save = new StagedSave(_vm->getEndianness()); + + _saveFiles[0].destName = new char[strlen(targetName) + 5]; + _saveFiles[1].destName = 0; + _saveFiles[2].destName = 0; + + sprintf(_saveFiles[0].destName, "%s.s00", targetName); + + _varSize = 0; + _hasIndex = false; } SaveLoad_v6::~SaveLoad_v6() { + delete _save; + + delete[] _saveFiles[0].destName; } SaveLoad::SaveMode SaveLoad_v6::getSaveMode(const char *fileName) { @@ -63,4 +79,228 @@ SaveLoad::SaveMode SaveLoad_v6::getSaveMode(const char *fileName) { return kSaveModeNone; } +int SaveLoad_v6::getSaveType(const char *fileName) { + for (int i = 0; i < ARRAYSIZE(_saveFiles); i++) + if (!scumm_stricmp(fileName, _saveFiles[i].sourceName)) + return i; + + return -1; +} + +int32 SaveLoad_v6::getSizeVersioned(int type) { + assertInited(); + + switch (_saveFiles[type].type) { + case kSaveGame: + return getSizeGame(_saveFiles[type]); + default: + return -1; + } + + return -1; +} + +bool SaveLoad_v6::loadVersioned(int type, int16 dataVar, int32 size, int32 offset) { + assertInited(); + + switch (_saveFiles[type].type) { + case kSaveGame: + if (loadGame(_saveFiles[type], dataVar, size, offset)) + return true; + + warning("While loading from slot %d", getSlot(offset)); + break; + + default: + return -1; + } + + return false; +} + +bool SaveLoad_v6::saveVersioned(int type, int16 dataVar, int32 size, int32 offset) { + assertInited(); + + switch (_saveFiles[type].type) { + case kSaveGame: + if (saveGame(_saveFiles[type], dataVar, size, offset)) + return true; + + warning("While saving to slot %d", getSlot(offset)); + break; + + default: + return -1; + } + + return false; +} + +int SaveLoad_v6::getSlot(int32 offset) const { + return ((offset - 2900) / _varSize); +} + +int SaveLoad_v6::getSlotRemainder(int32 offset) const { + return ((offset - 2900) % _varSize); +} + +int32 SaveLoad_v6::getSizeGame(SaveFile &saveFile) { + if (!_hasIndex) + return -1; + + Common::SaveFileManager *saveMan = g_system->getSavefileManager(); + Common::InSaveFile *in; + + for (int i = 60; i >= 0; i--) { + in = saveMan->openForLoading(setCurrentSlot(saveFile.destName, i)); + if (in) { + delete in; + return (i + 1) * _varSize + 2900; + } + } + + return -1; +} + +bool SaveLoad_v6::loadGame(SaveFile &saveFile, + int16 dataVar, int32 size, int32 offset) { + + if (size == 0) { + dataVar = 0; + size = _varSize; + } + + if (offset < 2900) { + debugC(3, kDebugSaveLoad, "Saving save index"); + + if ((offset + size) > 2900) { + warning("Wrong index size (%d, %d)", size, offset); + return false; + } + + if (!_hasIndex) { + warning("No index written yet"); + return false; + } + + refreshIndex(); + + byte *sizes = new byte[size]; + memset(sizes, 0, size); + + _vm->_inter->_variables->copyFrom(dataVar, _indexBuffer + offset, sizes, size); + + delete[] sizes; + + + } else { + int slot = getSlot(offset); + int slotRem = getSlotRemainder(offset); + + debugC(2, kDebugSaveLoad, "Loading from slot %d", slot); + + if ((slot >= 60) || (slotRem != 0)) { + warning("Invalid loading procedure (%d, %d, %d, %d, %d)", + dataVar, size, offset, slot, slotRem); + return false; + } + + refreshIndex(); + SaveLoad::setCurrentSlot(saveFile.destName, slot); + + if (!_save->load(dataVar, size, 40, saveFile.destName, _vm->_inter->_variables)) + return false; + + refreshIndex(); + } + + return true; +} + +bool SaveLoad_v6::saveGame(SaveFile &saveFile, + int16 dataVar, int32 size, int32 offset) { + + if (size == 0) { + dataVar = 0; + size = _varSize; + } + + if (offset < 2900) { + debugC(3, kDebugSaveLoad, "Saving save index"); + + if ((offset + size) > 2900) { + warning("Wrong index size (%d, %d)", size, offset); + return false; + } + + _vm->_inter->_variables->copyTo(dataVar, _indexBuffer + offset, 0, size); + _hasIndex = true; + + } else { + int slot = getSlot(offset); + int slotRem = getSlotRemainder(offset); + + debugC(2, kDebugSaveLoad, "Saving to slot %d", slot); + + if ((slot >= 60) || (slotRem != 0)) { + warning("Invalid saving procedure (%d, %d, %d, %d, %d)", + dataVar, size, offset, slot, slotRem); + return false; + } + + if (!_hasIndex) { + warning("No index written yet"); + return false; + } + + SaveLoad::setCurrentSlot(saveFile.destName, slot); + + byte sizes[40]; + memset(sizes, 0, 40); + if(!_save->save(0, 40, 0, saveFile.destName, _indexBuffer + 500 + (slot * 40), sizes)) + return false; + + if (!_save->save(dataVar, size, 40, saveFile.destName, _vm->_inter->_variables)) + return false; + + refreshIndex(); + } + + return true; +} + +void SaveLoad_v6::assertInited() { + if (_varSize > 0) + return; + + _varSize = _vm->_inter->_variables->getSize(); + + _save->addStage(40); + _save->addStage(_varSize); +} + +void SaveLoad_v6::refreshIndex() { + Common::SaveFileManager *saveMan = g_system->getSavefileManager(); + Common::InSaveFile *in; + + int32 max = -1; + byte *names = _indexBuffer + 500; + for (int i = 0; i < 60; i++, names += 40) { + in = saveMan->openForLoading(setCurrentSlot(_saveFiles[0].destName, i)); + if (in) { + max = i; + in->read(names, 40); + delete in; + } else + memset(names, 0, 40); + } + + WRITE_LE_UINT32(_indexBuffer + 160, max + 1); + + Common::OutSaveFile *out = saveMan->openForSaving("Foobar"); + out->write(_indexBuffer, 2900); + out->flush(); + delete out; +} + } // End of namespace Gob -- cgit v1.2.3