/** * DoRestore */ static bool DoRestore() { Common::InSaveFile *f = _vm->getSaveFileMan()->openForLoading(g_savedFiles[g_RestoreGameNumber].name); if (f == NULL) { return false; } Common::Serializer s(f, 0); SaveGameHeader hdr; if (!syncSaveGameHeader(s, hdr)) { delete f; // Invalid header, or savegame too new -> skip it return false; } DoSync(s); uint32 id = f->readSint32LE(); if (id != (uint32)0xFEEDFACE) error("Incompatible saved game"); bool failed = (f->eos() || f->err()); delete f; if (failed) { GUI::MessageDialog dialog(_("Failed to load game state from file.")); dialog.runModal(); } return !failed; }
/** * DoRestore */ static bool DoRestore() { Common::InSaveFile *f = _vm->getSaveFileMan()->openForLoading(g_savedFiles[g_RestoreGameNumber].name); if (f == NULL) { return false; } Common::Serializer s(f, 0); SaveGameHeader hdr; if (!syncSaveGameHeader(s, hdr)) { delete f; // Invalid header, or savegame too new -> skip it return false; } // Load in the data. For older savegame versions, we potentially need to load the data twice, once // for pre 1.5 savegames, and if that fails, a second time for 1.5 savegames int numInterpreters = hdr.numInterpreters; int32 currentPos = f->pos(); for (int tryNumber = 0; tryNumber < ((hdr.ver >= 2) ? 1 : 2); ++tryNumber) { // If it's the second loop iteration, try with the 1.5 savegame number of interpreter contexts if (tryNumber == 1) { f->seek(currentPos); numInterpreters = 80; } // Load the savegame data if (DoSync(s, numInterpreters)) // Data load was successful (or likely), so break out of loop break; } uint32 id = f->readSint32LE(); if (id != (uint32)0xFEEDFACE) error("Incompatible saved game"); bool failed = (f->eos() || f->err()); delete f; if (failed) { GUI::MessageDialog dialog(_("Failed to load game state from file.")); dialog.runModal(); } return !failed; }
bool DrasculaEngine::loadGame(const char *gameName) { int l, savedChapter, roomNum = 0; Common::InSaveFile *sav; previousMusic = roomMusic; _menuScreen = false; if (currentChapter != 1) clearRoom(); if (!(sav = _saveFileMan->openForLoading(gameName))) { error("missing savegame file"); } savedChapter = sav->readSint32LE(); if (savedChapter != currentChapter) { strcpy(saveName, gameName); currentChapter = savedChapter - 1; loadedDifferentChapter = 1; return false; } sav->read(currentData, 20); curX = sav->readSint32LE(); curY = sav->readSint32LE(); trackProtagonist = sav->readSint32LE(); for (l = 1; l < ARRAYSIZE(inventoryObjects); l++) { inventoryObjects[l] = sav->readSint32LE(); } for (l = 0; l < NUM_FLAGS; l++) { flags[l] = sav->readSint32LE(); } takeObject = sav->readSint32LE(); pickedObject = sav->readSint32LE(); loadedDifferentChapter = 0; if (!sscanf(currentData, "%d.ald", &roomNum)) { error("Bad save format"); } enterRoom(roomNum); selectVerb(kVerbNone); return true; }
void SagaEngine::load(const char *fileName) { Common::InSaveFile *in; int commonBufferSize; int sceneNumber, insetSceneNumber; int mapx, mapy; char title[TITLESIZE]; if (!(in = _saveFileMan->openForLoading(fileName))) { return; } _saveHeader.type = in->readUint32BE(); _saveHeader.size = in->readUint32LE(); _saveHeader.version = in->readUint32LE(); in->read(_saveHeader.name, sizeof(_saveHeader.name)); // Some older saves were not written in an endian safe fashion. // We try to detect this here by checking for extremly high version values. // If found, we retry with the data swapped. if (_saveHeader.version > 0xFFFFFF) { warning("This savegame is not endian safe, retrying with the data swapped"); _saveHeader.version = SWAP_BYTES_32(_saveHeader.version); } debug(2, "Save version: 0x%X", _saveHeader.version); if (_saveHeader.version < 4) warning("This savegame is not endian-safe. There may be problems"); if (_saveHeader.type != MKTAG('S','A','G','A')) { error("SagaEngine::load wrong save game format"); } if (_saveHeader.version > 4) { in->read(title, TITLESIZE); debug(0, "Save is for: %s", title); } if (_saveHeader.version >= 6) { // We don't need the thumbnail here, so just read it and discard it Graphics::skipThumbnail(*in); in->readUint32BE(); // save date in->readUint16BE(); // save time if (_saveHeader.version >= 8) { uint32 playTime = in->readUint32BE(); g_engine->setTotalPlayTime(playTime * 1000); } } // Clear pending events here, and don't process queued music events _events->clearList(false); // Surrounding scene sceneNumber = in->readSint32LE(); #ifdef ENABLE_IHNM if (getGameId() == GID_IHNM) { int currentChapter = _scene->currentChapterNumber(); _scene->setChapterNumber(in->readSint32LE()); in->skip(4); // obsolete, was used for setting the protagonist if (_scene->currentChapterNumber() != currentChapter) _scene->changeScene(-2, 0, kTransitionFade, _scene->currentChapterNumber()); _scene->setCurrentMusicTrack(in->readSint32LE()); _scene->setCurrentMusicRepeat(in->readSint32LE()); _music->stop(); if (_scene->currentChapterNumber() == 8) _interface->setMode(kPanelChapterSelection); if (!isIHNMDemo()) { _music->play(_music->_songTable[_scene->getCurrentMusicTrack()], _scene->getCurrentMusicRepeat() ? MUSIC_LOOP : MUSIC_NORMAL); } else { _music->play(3, MUSIC_LOOP); } } #endif // Inset scene insetSceneNumber = in->readSint32LE(); #ifdef ENABLE_IHNM if (getGameId() == GID_IHNM) { _globalFlags = in->readUint32LE(); for (int i = 0; i < ARRAYSIZE(_ethicsPoints); i++) _ethicsPoints[i] = in->readSint16LE(); } #endif _interface->loadState(in); _actor->loadState(in); commonBufferSize = in->readSint16LE(); _script->_commonBuffer.resize(commonBufferSize); in->read(_script->_commonBuffer.getBuffer(), commonBufferSize); if (getGameId() == GID_ITE) { mapx = in->readSint16LE(); mapy = in->readSint16LE(); _isoMap->setMapPosition(mapx, mapy); } // Note: the mapx, mapy ISO map positions were incorrectly saved // for IHNM too, which has no ISO map scenes, up to save version 6. // Since they're at the end of the savegame, we just ignore them delete in; // Mute volume to prevent outScene music play int volume = _music->getVolume(); _music->setVolume(0); _scene->clearSceneQueue(); _scene->changeScene(sceneNumber, ACTOR_NO_ENTRANCE, kTransitionNoFade); _events->handleEvents(0); //dissolve backgrounds if (insetSceneNumber != sceneNumber) { _render->setFlag(RF_DISABLE_ACTORS); _scene->draw(); _render->drawScene(); _render->clearFlag(RF_DISABLE_ACTORS); _scene->changeScene(insetSceneNumber, ACTOR_NO_ENTRANCE, kTransitionNoFade); } _music->setVolume(volume); _interface->draw(); // Abort any scene entry protagonist animations and auto-cue speeches. // Fixes bug #10009. _actor->abortAllSpeeches(); _actor->_protagonist->_location = _actor->_protagonist->_finalTarget; _actor->actorEndWalk(ID_PROTAG, true); }