diff options
-rw-r--r-- | engines/zvision/module.mk | 1 | ||||
-rw-r--r-- | engines/zvision/save_manager.cpp | 176 | ||||
-rw-r--r-- | engines/zvision/save_manager.h | 39 |
3 files changed, 215 insertions, 1 deletions
diff --git a/engines/zvision/module.mk b/engines/zvision/module.mk index 48b8a66077..c8c60ca8ce 100644 --- a/engines/zvision/module.mk +++ b/engines/zvision/module.mk @@ -17,6 +17,7 @@ MODULE_OBJS := \ render_manager.o \ render_table.o \ rlf_animation.o \ + save_manager.o \ scr_file_handling.o \ script_manager.o \ scripts.o \ diff --git a/engines/zvision/save_manager.cpp b/engines/zvision/save_manager.cpp new file mode 100644 index 0000000000..9611b9c9b7 --- /dev/null +++ b/engines/zvision/save_manager.cpp @@ -0,0 +1,176 @@ +/* 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. + + * 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. + * + */ + +#include "common/scummsys.h" + +#include "common/system.h" + +#include "graphics/surface.h" +#include "graphics/thumbnail.h" + +#include "zvision/save_manager.h" +#include "zvision/zvision.h" +#include "zvision/script_manager.h" + + +namespace ZVision { + +const uint32 SaveManager::SAVEGAME_ID = MKTAG('Z', 'E', 'N', 'G'); + +void SaveManager::saveGame(uint slot, const Common::String &saveName) { + Common::SaveFileManager *saveFileManager = g_system->getSavefileManager(); + Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot)); + + // Write out the savegame header + file->writeUint32BE(SAVEGAME_ID); + + // Write savegame name + file->writeString(saveName); + file->writeByte(0); + + // We can't call writeGameSaveData because the save menu is actually + // a room, so writeGameSaveData would save us in the save menu. + // However, an auto save is performed before each room change, so we + // can copy the data from there. We can guarantee that an auto save file will + // exist before this is called because the save menu can only be accessed + // after the first room (the main menu) has loaded. + Common::InSaveFile *autoSaveFile = saveFileManager->openForLoading(_engine->generateAutoSaveFileName()); + + // Skip over the header info + autoSaveFile->readSint32BE(); // SAVEGAME_ID + autoSaveFile->seek(5, SEEK_CUR); // The string "auto" with terminating NULL + + // Read the rest to a buffer + uint32 size = autoSaveFile->size() - autoSaveFile->pos(); + byte *buffer = new byte[size]; + autoSaveFile->read(buffer, size); + + // Then write the buffer to the new file + file->write(buffer, size); + + // Cleanup + delete[] buffer; + file->finalize(); +} + +void SaveManager::autoSave() { + Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(_engine->generateAutoSaveFileName()); + + // Write out the savegame header + file->writeUint32BE(SAVEGAME_ID); + + file->writeString("auto"); + file->writeByte(0); + + writeSaveGameData(file); + + file->finalize(); +} + +void SaveManager::writeSaveGameData(Common::OutSaveFile *file) { + // Create a thumbnail and save it + Graphics::saveThumbnail(*file); + + // Write out the save date/time + TimeDate td; + g_system->getTimeAndDate(td); + file->writeSint16LE(td.tm_year + 1900); + file->writeSint16LE(td.tm_mon + 1); + file->writeSint16LE(td.tm_mday); + file->writeSint16LE(td.tm_hour); + file->writeSint16LE(td.tm_min); + + ScriptManager *scriptManager = _engine->getScriptManager(); + // Write out the current location + Location currentLocation = scriptManager->getCurrentLocation(); + file->writeByte(currentLocation.world); + file->writeByte(currentLocation.room); + file->writeByte(currentLocation.node); + file->writeByte(currentLocation.view); + file->writeUint32LE(currentLocation.offset); + + // Write out the current state table values + scriptManager->serializeStateTable(file); + + // Write out any controls needing to save state + scriptManager->serializeControls(file); +} + +Common::Error SaveManager::loadGame(uint slot) { + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(_engine->generateSaveFileName(slot)); + if (saveFile == 0) { + return Common::kPathDoesNotExist; + } + + // Read the header + SaveGameHeader header; + if (!readSaveGameHeader(saveFile, header)) { + return Common::kUnknownError; + } + + char world = (char)saveFile->readByte(); + char room = (char)saveFile->readByte(); + char node = (char)saveFile->readByte(); + char view = (char)saveFile->readByte(); + uint32 offset = (char)saveFile->readUint32LE(); + + ScriptManager *scriptManager = _engine->getScriptManager(); + // Load the room + scriptManager->changeLocation(world, room, node, view, offset); + + // Update the state table values + scriptManager->deserializeStateTable(saveFile); + + // Update the controls + scriptManager->deserializeControls(saveFile); + + return Common::kNoError; +} + +bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) { + if (in->readSint32BE() != SAVEGAME_ID) { + warning("File is not a ZVision save file. Aborting load"); + return false; + } + + // Read in the save name + header.saveName.clear(); + char ch; + while ((ch = (char)in->readByte()) != '\0') + header.saveName += ch; + + // Get the thumbnail + header.thumbnail = Graphics::loadThumbnail(*in); + if (!header.thumbnail) + return false; + + // Read in save date/time + header.saveYear = in->readSint16LE(); + header.saveMonth = in->readSint16LE(); + header.saveDay = in->readSint16LE(); + header.saveHour = in->readSint16LE(); + header.saveMinutes = in->readSint16LE(); + + return true; +} + +} // End of namespace ZVision diff --git a/engines/zvision/save_manager.h b/engines/zvision/save_manager.h index 487cf203fb..ae65750b42 100644 --- a/engines/zvision/save_manager.h +++ b/engines/zvision/save_manager.h @@ -23,6 +23,43 @@ #ifndef ZVISION_SAVE_MANAGER_H #define ZVISION_SAVE_MANAGER_H -// TODO: Implement SaveManager +#include "common/types.h" + +#include "common/savefile.h" + +namespace Common { +class String; +} + +namespace ZVision { + +class ZVision; + +struct SaveGameHeader { + Common::String saveName; + Graphics::Surface *thumbnail; + int saveYear, saveMonth, saveDay; + int saveHour, saveMinutes; +}; + +class SaveManager { +public: + SaveManager(ZVision *engine); + +private: + ZVision *_engine; + static const uint32 SAVEGAME_ID; + +public: + void autoSave(); + void saveGame(uint slot, const Common::String &saveName); + Common::Error loadGame(uint slot); + +private: + void writeSaveGameData(Common::OutSaveFile *file); + bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header); +}; + +} // End of namespace ZVision #endif |