diff options
Diffstat (limited to 'engines/zvision/core')
-rw-r--r-- | engines/zvision/core/console.cpp | 119 | ||||
-rw-r--r-- | engines/zvision/core/events.cpp | 93 | ||||
-rw-r--r-- | engines/zvision/core/menu.h | 94 | ||||
-rw-r--r-- | engines/zvision/core/save_manager.cpp | 166 | ||||
-rw-r--r-- | engines/zvision/core/save_manager.h | 9 |
5 files changed, 315 insertions, 166 deletions
diff --git a/engines/zvision/core/console.cpp b/engines/zvision/core/console.cpp index e610f34474..252a4b75ef 100644 --- a/engines/zvision/core/console.cpp +++ b/engines/zvision/core/console.cpp @@ -1,37 +1,37 @@ /* 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. - * - */ +* +* 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 "zvision/core/console.h" +#include "zvision/console.h" #include "zvision/zvision.h" -#include "zvision/scripting/script_manager.h" -#include "zvision/graphics/render_manager.h" -#include "zvision/strings/string_manager.h" -#include "zvision/video/zork_avi_decoder.h" -#include "zvision/sound/zork_raw.h" -#include "zvision/utility/utility.h" -#include "zvision/cursors/cursor.h" +#include "zvision/script_manager.h" +#include "zvision/render_manager.h" +#include "zvision/string_manager.h" +#include "zvision/zork_avi_decoder.h" +#include "zvision/zork_raw.h" +#include "zvision/utility.h" +#include "zvision/cursor.h" #include "common/system.h" #include "common/file.h" @@ -45,34 +45,34 @@ namespace ZVision { Console::Console(ZVision *engine) : GUI::Debugger(), _engine(engine) { - registerCmd("loadimage", WRAP_METHOD(Console, cmdLoadImage)); - registerCmd("loadvideo", WRAP_METHOD(Console, cmdLoadVideo)); - registerCmd("loadsound", WRAP_METHOD(Console, cmdLoadSound)); - registerCmd("raw2wav", WRAP_METHOD(Console, cmdRawToWav)); - registerCmd("setrenderstate", WRAP_METHOD(Console, cmdSetRenderState)); - registerCmd("generaterendertable", WRAP_METHOD(Console, cmdGenerateRenderTable)); - registerCmd("setpanoramafov", WRAP_METHOD(Console, cmdSetPanoramaFoV)); - registerCmd("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale)); - registerCmd("changelocation", WRAP_METHOD(Console, cmdChangeLocation)); - registerCmd("dumpfile", WRAP_METHOD(Console, cmdDumpFile)); - registerCmd("parseallscrfiles", WRAP_METHOD(Console, cmdParseAllScrFiles)); - registerCmd("rendertext", WRAP_METHOD(Console, cmdRenderText)); + DCmd_Register("loadimage", WRAP_METHOD(Console, cmdLoadImage)); + DCmd_Register("loadvideo", WRAP_METHOD(Console, cmdLoadVideo)); + DCmd_Register("loadsound", WRAP_METHOD(Console, cmdLoadSound)); + DCmd_Register("raw2wav", WRAP_METHOD(Console, cmdRawToWav)); + DCmd_Register("setrenderstate", WRAP_METHOD(Console, cmdSetRenderState)); + DCmd_Register("generaterendertable", WRAP_METHOD(Console, cmdGenerateRenderTable)); + DCmd_Register("setpanoramafov", WRAP_METHOD(Console, cmdSetPanoramaFoV)); + DCmd_Register("setpanoramascale", WRAP_METHOD(Console, cmdSetPanoramaScale)); + DCmd_Register("changelocation", WRAP_METHOD(Console, cmdChangeLocation)); + DCmd_Register("dumpfile", WRAP_METHOD(Console, cmdDumpFile)); + DCmd_Register("parseallscrfiles", WRAP_METHOD(Console, cmdParseAllScrFiles)); + DCmd_Register("rendertext", WRAP_METHOD(Console, cmdRenderText)); } bool Console::cmdLoadImage(int argc, const char **argv) { - if (argc == 4) - _engine->getRenderManager()->renderImageToScreen(argv[1], atoi(argv[2]), atoi(argv[3])); - else { - debugPrintf("Use loadimage <fileName> <destinationX> <destinationY> to load an image to the screen\n"); - return true; - } +// if (argc == 4) +// _engine->getRenderManager()->renderImageToScreen(argv[1], atoi(argv[2]), atoi(argv[3])); +// else { +// DebugPrintf("Use loadimage <fileName> <destinationX> <destinationY> to load an image to the screen\n"); +// return true; +// } return true; } bool Console::cmdLoadVideo(int argc, const char **argv) { if (argc != 2) { - debugPrintf("Use loadvideo <fileName> to load a video to the screen\n"); + DebugPrintf("Use loadvideo <fileName> to load a video to the screen\n"); return true; } @@ -86,7 +86,7 @@ bool Console::cmdLoadVideo(int argc, const char **argv) { bool Console::cmdLoadSound(int argc, const char **argv) { if (!Common::File::exists(argv[1])) { - debugPrintf("File does not exist\n"); + DebugPrintf("File does not exist\n"); return true; } @@ -105,7 +105,7 @@ bool Console::cmdLoadSound(int argc, const char **argv) { Audio::SoundHandle handle; _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, soundStream, -1, 100, 0, DisposeAfterUse::YES, false, false); } else { - debugPrintf("Use loadsound <fileName> [<rate> <isStereo: 1 or 0>] to load a sound\n"); + DebugPrintf("Use loadsound <fileName> [<rate> <isStereo: 1 or 0>] to load a sound\n"); return true; } @@ -114,7 +114,7 @@ bool Console::cmdLoadSound(int argc, const char **argv) { bool Console::cmdRawToWav(int argc, const char **argv) { if (argc != 3) { - debugPrintf("Use raw2wav <rawFilePath> <wavFileName> to dump a .RAW file to .WAV\n"); + DebugPrintf("Use raw2wav <rawFilePath> <wavFileName> to dump a .RAW file to .WAV\n"); return true; } @@ -124,7 +124,7 @@ bool Console::cmdRawToWav(int argc, const char **argv) { bool Console::cmdSetRenderState(int argc, const char **argv) { if (argc != 2) { - debugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n"); + DebugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n"); return true; } @@ -137,7 +137,7 @@ bool Console::cmdSetRenderState(int argc, const char **argv) { else if (renderState.matchString("flat", true)) _engine->getRenderManager()->getRenderTable()->setRenderState(RenderTable::FLAT); else - debugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n"); + DebugPrintf("Use setrenderstate <RenderState: panorama, tilt, flat> to change the current render state\n"); return true; } @@ -150,7 +150,7 @@ bool Console::cmdGenerateRenderTable(int argc, const char **argv) { bool Console::cmdSetPanoramaFoV(int argc, const char **argv) { if (argc != 2) { - debugPrintf("Use setpanoramafov <fieldOfView> to change the current panorama field of view\n"); + DebugPrintf("Use setpanoramafov <fieldOfView> to change the current panorama field of view\n"); return true; } @@ -161,7 +161,7 @@ bool Console::cmdSetPanoramaFoV(int argc, const char **argv) { bool Console::cmdSetPanoramaScale(int argc, const char **argv) { if (argc != 2) { - debugPrintf("Use setpanoramascale <scale> to change the current panorama scale\n"); + DebugPrintf("Use setpanoramascale <scale> to change the current panorama scale\n"); return true; } @@ -172,7 +172,7 @@ bool Console::cmdSetPanoramaScale(int argc, const char **argv) { bool Console::cmdChangeLocation(int argc, const char **argv) { if (argc != 6) { - debugPrintf("Use changelocation <char: world> <char: room> <char:node> <char:view> <int: x position> to change your location\n"); + DebugPrintf("Use changelocation <char: world> <char: room> <char:node> <char:view> <int: x position> to change your location\n"); return true; } @@ -183,7 +183,7 @@ bool Console::cmdChangeLocation(int argc, const char **argv) { bool Console::cmdDumpFile(int argc, const char **argv) { if (argc != 2) { - debugPrintf("Use dumpfile <fileName> to dump a file\n"); + DebugPrintf("Use dumpfile <fileName> to dump a file\n"); return true; } @@ -197,7 +197,6 @@ bool Console::cmdParseAllScrFiles(int argc, const char **argv) { SearchMan.listMatchingMembers(list, "*.scr"); for (Common::ArchiveMemberList::iterator iter = list.begin(); iter != list.end(); ++iter) { - _engine->getScriptManager()->parseScrFile((*iter)->getName()); } return true; @@ -205,12 +204,12 @@ bool Console::cmdParseAllScrFiles(int argc, const char **argv) { bool Console::cmdRenderText(int argc, const char **argv) { if (argc != 7) { - debugPrintf("Use rendertext <text> <fontNumber> <destX> <destY> <maxWidth> <1 or 0: wrap> to render text\n"); + DebugPrintf("Use rendertext <text> <fontNumber> <destX> <destY> <maxWidth> <1 or 0: wrap> to render text\n"); return true; } - StringManager::TextStyle style = _engine->getStringManager()->getTextStyle(atoi(argv[2])); - _engine->getRenderManager()->renderTextToWorkingWindow(333, Common::String(argv[1]), style.font, atoi(argv[3]), atoi(argv[4]), style.color, atoi(argv[5]), -1, Graphics::kTextAlignLeft, atoi(argv[6]) == 0 ? false : true); + //StringManager::TextStyle style = _engine->getStringManager()->getTextStyle(atoi(argv[2])); + //_engine->getRenderManager()->renderTextToWorkingWindow(333, Common::String(argv[1]), style.font, atoi(argv[3]), atoi(argv[4]), style.color, atoi(argv[5]), -1, Graphics::kTextAlignLeft, atoi(argv[6]) == 0 ? false : true); return true; } diff --git a/engines/zvision/core/events.cpp b/engines/zvision/core/events.cpp index 83d6c17dec..189bf007c1 100644 --- a/engines/zvision/core/events.cpp +++ b/engines/zvision/core/events.cpp @@ -8,12 +8,12 @@ * 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. @@ -24,11 +24,12 @@ #include "zvision/zvision.h" -#include "zvision/core/console.h" -#include "zvision/cursors/cursor_manager.h" -#include "zvision/graphics/render_manager.h" -#include "zvision/scripting/script_manager.h" -#include "zvision/animation/rlf_animation.h" +#include "zvision/console.h" +#include "zvision/cursor_manager.h" +#include "zvision/render_manager.h" +#include "zvision/script_manager.h" +#include "zvision/rlf_animation.h" +#include "zvision/menu.h" #include "common/events.h" #include "common/system.h" @@ -43,17 +44,28 @@ void ZVision::processEvents() { while (_eventMan->pollEvent(_event)) { switch (_event.type) { case Common::EVENT_LBUTTONDOWN: + _cursorManager->cursorDown(true); + _scriptManager->setStateValue(StateKey_LMouse, 1); onMouseDown(_event.mouse); break; case Common::EVENT_LBUTTONUP: + _cursorManager->cursorDown(false); + _scriptManager->setStateValue(StateKey_LMouse, 0); onMouseUp(_event.mouse); break; case Common::EVENT_RBUTTONDOWN: + _cursorManager->cursorDown(true); + _scriptManager->setStateValue(StateKey_RMouse, 1); // TODO: Inventory logic break; + case Common::EVENT_RBUTTONUP: + _cursorManager->cursorDown(false); + _scriptManager->setStateValue(StateKey_RMouse, 0); + break; + case Common::EVENT_MOUSEMOVE: onMouseMove(_event.mouse); break; @@ -87,23 +99,24 @@ void ZVision::processEvents() { } void ZVision::onMouseDown(const Common::Point &pos) { - _cursorManager->cursorDown(true); + _menu->onMouseDown(pos); Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos)); _scriptManager->onMouseDown(pos, imageCoord); } void ZVision::onMouseUp(const Common::Point &pos) { - _cursorManager->cursorDown(false); + _menu->onMouseUp(pos); Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos)); _scriptManager->onMouseUp(pos, imageCoord); } void ZVision::onMouseMove(const Common::Point &pos) { + _menu->onMouseMove(pos); Common::Point imageCoord(_renderManager->screenSpaceToImageSpace(pos)); - bool cursorWasChanged = _scriptManager->onMouseMove(pos, imageCoord); + bool cursorWasChanged = false; // Graph of the function governing rotation velocity: // @@ -136,50 +149,62 @@ void ZVision::onMouseMove(const Common::Point &pos) { // ^ if (_workingWindow.contains(pos)) { + cursorWasChanged = _scriptManager->onMouseMove(pos, imageCoord); + RenderTable::RenderState renderState = _renderManager->getRenderTable()->getRenderState(); if (renderState == RenderTable::PANORAMA) { if (pos.x >= _workingWindow.left && pos.x < _workingWindow.left + ROTATION_SCREEN_EDGE_OFFSET) { - // Linear function of distance to the left edge (y = -mx + b) - // We use fixed point math to get better accuracy - Common::Rational velocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.x - _workingWindow.left)) - MAX_ROTATION_SPEED; - _renderManager->setBackgroundVelocity(velocity.toInt()); - _cursorManager->setLeftCursor(); + + int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4; + if (mspeed <= 0) + mspeed = 400 >> 4; + _velocity = (((pos.x - (ROTATION_SCREEN_EDGE_OFFSET + _workingWindow.left)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7; + + _cursorManager->changeCursor(CursorIndex_Left); cursorWasChanged = true; } else if (pos.x <= _workingWindow.right && pos.x > _workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET) { - // Linear function of distance to the right edge (y = mx) - // We use fixed point math to get better accuracy - Common::Rational velocity = Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.x - _workingWindow.right + ROTATION_SCREEN_EDGE_OFFSET); - _renderManager->setBackgroundVelocity(velocity.toInt()); - _cursorManager->setRightCursor(); + + int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4; + if (mspeed <= 0) + mspeed = 400 >> 4; + _velocity = (((pos.x - (_workingWindow.right - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7; + + _cursorManager->changeCursor(CursorIndex_Right); cursorWasChanged = true; } else { - _renderManager->setBackgroundVelocity(0); + _velocity = 0; } } else if (renderState == RenderTable::TILT) { if (pos.y >= _workingWindow.top && pos.y < _workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET) { - // Linear function of distance to top edge - // We use fixed point math to get better accuracy - Common::Rational velocity = (Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.top)) - MAX_ROTATION_SPEED; - _renderManager->setBackgroundVelocity(velocity.toInt()); - _cursorManager->setUpCursor(); + + int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4; + if (mspeed <= 0) + mspeed = 400 >> 4; + _velocity = (((pos.y - (_workingWindow.top + ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7; + + _cursorManager->changeCursor(CursorIndex_UpArr); cursorWasChanged = true; } else if (pos.y <= _workingWindow.bottom && pos.y > _workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET) { - // Linear function of distance to the bottom edge (y = mx) - // We use fixed point math to get better accuracy - Common::Rational velocity = Common::Rational(MAX_ROTATION_SPEED, ROTATION_SCREEN_EDGE_OFFSET) * (pos.y - _workingWindow.bottom + ROTATION_SCREEN_EDGE_OFFSET); - _renderManager->setBackgroundVelocity(velocity.toInt()); - _cursorManager->setDownCursor(); + + int16 mspeed = _scriptManager->getStateValue(StateKey_RotateSpeed) >> 4; + if (mspeed <= 0) + mspeed = 400 >> 4; + _velocity = (((pos.y - (_workingWindow.bottom - ROTATION_SCREEN_EDGE_OFFSET)) << 7) / ROTATION_SCREEN_EDGE_OFFSET * mspeed) >> 7; + + _cursorManager->changeCursor(CursorIndex_DownArr); cursorWasChanged = true; } else { - _renderManager->setBackgroundVelocity(0); + _velocity = 0; } + } else { + _velocity = 0; } } else { - _renderManager->setBackgroundVelocity(0); + _velocity = 0; } if (!cursorWasChanged) { - _cursorManager->revertToIdle(); + _cursorManager->changeCursor(CursorIndex_Idle); } } diff --git a/engines/zvision/core/menu.h b/engines/zvision/core/menu.h index 3ab6d4c2ec..7be03f62ef 100644 --- a/engines/zvision/core/menu.h +++ b/engines/zvision/core/menu.h @@ -23,6 +23,98 @@ #ifndef ZVISION_MENU_H #define ZVISION_MENU_H -// TODO: Implement MenuHandler +#include "graphics/surface.h" +#include "common/rect.h" + +#include "zvision/zvision.h" +#include "zvision/script_manager.h" + +namespace ZVision { + +enum menuBar { + menuBar_Exit = 0x1, + menuBar_Settings = 0x2, + menuBar_Restore = 0x4, + menuBar_Save = 0x8, + menuBar_Items = 0x100, + menuBar_Magic = 0x200 +}; + +class menuHandler { +public: + menuHandler(ZVision *engine); + virtual ~menuHandler() {}; + virtual void onMouseMove(const Common::Point &Pos) {}; + virtual void onMouseDown(const Common::Point &Pos) {}; + virtual void onMouseUp(const Common::Point &Pos) {}; + virtual void process(uint32 deltaTimeInMillis) {}; +protected: + uint16 menu_bar_flag; + ZVision *_engine; +}; + +class menuZgi: public menuHandler { +public: + menuZgi(ZVision *engine); + ~menuZgi(); + void onMouseMove(const Common::Point &Pos); + void onMouseUp(const Common::Point &Pos); + void process(uint32 deltaTimeInMillis); +private: + Graphics::Surface menuback[3][2]; + Graphics::Surface menubar[4][2]; + + + Graphics::Surface *items[50][2]; + uint item_id[50]; + + Graphics::Surface *magic[12][2]; + uint magic_id[12]; + + int menu_mousefocus; + bool inmenu; + + int mouse_on_item; + + bool scrolled[3]; + float scrollPos[3]; + + enum { + menu_ITEM = 0, + menu_MAGIC = 1, + menu_MAIN = 2 + }; + + bool clean; + bool redraw; + +}; + +class menuNem: public menuHandler { +public: + menuNem(ZVision *engine); + ~menuNem(); + void onMouseMove(const Common::Point &Pos); + void onMouseUp(const Common::Point &Pos); + void process(uint32 deltaTimeInMillis); +private: + Graphics::Surface but[4][6]; + Graphics::Surface menubar; + + bool inmenu; + + int mouse_on_item; + + bool scrolled; + float scrollPos; + + bool redraw; + + int frm; + int16 delay; + +}; + +} #endif diff --git a/engines/zvision/core/save_manager.cpp b/engines/zvision/core/save_manager.cpp index 07fb7637e7..8ec4f4d628 100644 --- a/engines/zvision/core/save_manager.cpp +++ b/engines/zvision/core/save_manager.cpp @@ -42,44 +42,27 @@ const uint32 SaveManager::SAVEGAME_ID = MKTAG('Z', 'E', 'N', 'G'); void SaveManager::saveGame(uint slot, const Common::String &saveName) { // The games only support 20 slots - assert(slot <= 1 && slot <= 20); + //assert(slot <= 1 && slot <= 20); Common::SaveFileManager *saveFileManager = g_system->getSavefileManager(); Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot)); - // Write out the savegame header - file->writeUint32BE(SAVEGAME_ID); - - // Write version - file->writeByte(SAVE_VERSION); + writeSaveGameHeader(file, saveName); - // Write savegame name - file->writeString(saveName); - file->writeByte(0); + _engine->getScriptManager()->serialize(file); - // 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()); + file->finalize(); + delete file; +} - // Skip over the header info - autoSaveFile->readSint32BE(); // SAVEGAME_ID - autoSaveFile->readByte(); // Version - autoSaveFile->seek(5, SEEK_CUR); // The string "auto" with terminating NULL +void SaveManager::saveGame(uint slot, const Common::String &saveName, Common::MemoryWriteStreamDynamic *stream) { + Common::SaveFileManager *saveFileManager = g_system->getSavefileManager(); + Common::OutSaveFile *file = saveFileManager->openForSaving(_engine->generateSaveFileName(slot)); - // Read the rest to a buffer - uint32 size = autoSaveFile->size() - autoSaveFile->pos(); - byte *buffer = new byte[size]; - autoSaveFile->read(buffer, size); + writeSaveGameHeader(file, saveName); - // Then write the buffer to the new file - file->write(buffer, size); + file->write(stream->getData(), stream->size()); - // Cleanup - delete[] buffer; file->finalize(); delete file; } @@ -87,26 +70,29 @@ void SaveManager::saveGame(uint slot, const Common::String &saveName) { void SaveManager::autoSave() { Common::OutSaveFile *file = g_system->getSavefileManager()->openForSaving(_engine->generateAutoSaveFileName()); - // Write out the savegame header - file->writeUint32BE(SAVEGAME_ID); + writeSaveGameHeader(file, "auto"); - // Version - file->writeByte(SAVE_VERSION); - - file->writeString("auto"); - file->writeByte(0); - - writeSaveGameData(file); + _engine->getScriptManager()->serialize(file); // Cleanup file->finalize(); delete file; } -void SaveManager::writeSaveGameData(Common::OutSaveFile *file) { +void SaveManager::writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName) { + + file->writeUint32BE(SAVEGAME_ID); + + // Write version + file->writeByte(SAVE_VERSION); + + // Write savegame name + file->writeString(saveName); + file->writeByte(0); + // Create a thumbnail and save it Graphics::saveThumbnail(*file); - + // Write out the save date/time TimeDate td; g_system->getTimeAndDate(td); @@ -115,28 +101,13 @@ void SaveManager::writeSaveGameData(Common::OutSaveFile *file) { 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) { // The games only support 20 slots - assert(slot <= 1 && slot <= 20); + //assert(slot <= 1 && slot <= 20); - Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(_engine->generateSaveFileName(slot)); + Common::SeekableReadStream *saveFile = getSlotFile(slot); if (saveFile == 0) { return Common::kPathDoesNotExist; } @@ -147,31 +118,63 @@ Common::Error SaveManager::loadGame(uint slot) { 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(); // Update the state table values - scriptManager->deserializeStateTable(saveFile); + scriptManager->deserialize(saveFile); + + delete saveFile; + if (header.thumbnail) + delete header.thumbnail; + + return Common::kNoError; +} + +Common::Error SaveManager::loadGame(const Common::String &saveName) { + Common::File *saveFile = _engine->getSearchManager()->openFile(saveName); + if (saveFile == NULL) { + saveFile = new Common::File; + if (!saveFile->open(saveName)) { + delete saveFile; + return Common::kPathDoesNotExist; + } + } + + // Read the header + SaveGameHeader header; + if (!readSaveGameHeader(saveFile, header)) { + return Common::kUnknownError; + } - // Load the room - scriptManager->changeLocation(world, room, node, view, offset); + ScriptManager *scriptManager = _engine->getScriptManager(); + // Update the state table values + scriptManager->deserialize(saveFile); - // Update the controls - scriptManager->deserializeControls(saveFile); + delete saveFile; + if (header.thumbnail) + delete header.thumbnail; return Common::kNoError; } bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) { - if (in->readUint32BE() != SAVEGAME_ID) { + uint32 tag = in->readUint32BE(); + if (tag == MKTAG('Z', 'N', 'S', 'G')) { + header.saveYear = 0; + header.saveMonth = 0; + header.saveDay = 0; + header.saveHour = 0; + header.saveMinutes = 0; + header.saveName = "Original Save"; + header.thumbnail = NULL; + header.version = SAVE_ORIGINAL; + in->seek(-4, SEEK_CUR); + return true; + } + if (tag != SAVEGAME_ID) { warning("File is not a ZVision save file. Aborting load"); return false; } - + // Read in the version header.version = in->readByte(); @@ -203,4 +206,29 @@ bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &hea return true; } +Common::SeekableReadStream *SaveManager::getSlotFile(uint slot) { + Common::SeekableReadStream *saveFile = g_system->getSavefileManager()->openForLoading(_engine->generateSaveFileName(slot)); + if (saveFile == NULL) { + // Try to load standart save file + Common::String filename; + if (_engine->getGameId() == GID_GRANDINQUISITOR) + filename.format("inqsav%u.sav", slot); + else if (_engine->getGameId() == GID_NEMESIS) + filename.format("nemsav%u.sav", slot); + + saveFile = _engine->getSearchManager()->openFile(filename); + if (saveFile == NULL) { + Common::File *tmpFile = new Common::File; + if (!tmpFile->open(filename)) { + delete tmpFile; + } else { + saveFile = tmpFile; + } + } + + } + + return saveFile; +} + } // End of namespace ZVision diff --git a/engines/zvision/core/save_manager.h b/engines/zvision/core/save_manager.h index 43fb0c0faf..8ed64a3fdc 100644 --- a/engines/zvision/core/save_manager.h +++ b/engines/zvision/core/save_manager.h @@ -24,6 +24,7 @@ #define ZVISION_SAVE_MANAGER_H #include "common/savefile.h" +#include "common/memstream.h" namespace Common { class String; @@ -54,6 +55,7 @@ private: static const uint32 SAVEGAME_ID; enum { + SAVE_ORIGINAL = 0, SAVE_VERSION = 1 }; @@ -73,6 +75,7 @@ public: * @param saveName The internal name for this save. This is NOT the name of the actual save file. */ void saveGame(uint slot, const Common::String &saveName); + void saveGame(uint slot, const Common::String &saveName, Common::MemoryWriteStreamDynamic *stream); /** * Loads the state data from the save file that slot references. Uses * ZVision::generateSaveFileName(slot) to get the save file name. @@ -80,10 +83,12 @@ public: * @param slot The save slot to load. Must be [1, 20] */ Common::Error loadGame(uint slot); + Common::Error loadGame(const Common::String &saveName); + Common::SeekableReadStream *getSlotFile(uint slot); + bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header); private: - void writeSaveGameData(Common::OutSaveFile *file); - bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header); + void writeSaveGameHeader(Common::OutSaveFile *file, const Common::String &saveName); }; } // End of namespace ZVision |