SaveStateDescriptor GnapMetaEngine::querySaveMetaInfos(const char *target, int slot) const { Common::String fileName = Common::String::format("%s.%03d", target, slot); Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName); if (file) { char saveIdentBuffer[5]; file->read(saveIdentBuffer, 5); int32 version = file->readByte(); if (version > GNAP_SAVEGAME_VERSION) { delete file; return SaveStateDescriptor(); } Common::String saveName; char ch; while ((ch = (char)file->readByte()) != '\0') saveName += ch; SaveStateDescriptor desc(slot, saveName); if (version != 1) { Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file); desc.setThumbnail(thumbnail); } int year = file->readSint16LE(); int month = file->readSint16LE(); int day = file->readSint16LE(); int hour = file->readSint16LE(); int minutes = file->readSint16LE(); desc.setSaveDate(year, month, day); desc.setSaveTime(hour, minutes); delete file; return desc; } return SaveStateDescriptor(); }
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); }
bool AvalancheEngine::loadGame(const int16 slot) { Common::String fileName = getSaveFileName(slot); Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName); if (!f) return false; uint32 signature = f->readUint32LE(); if (signature != MKTAG('A', 'V', 'A', 'L')) return false; // Check version. We can't restore from obsolete versions. byte saveVersion = f->readByte(); if (saveVersion > kSavegameVersion) { warning("Savegame of incompatible version!"); delete f; return false; } // Read the description. uint32 descSize = f->readUint32LE(); Common::String description; for (uint32 i = 0; i < descSize; i++) { char actChar = f->readByte(); description += actChar; } description.toUppercase(); Graphics::skipThumbnail(*f); // Read the time the game was saved. TimeDate t; t.tm_mday = f->readSint16LE(); t.tm_mon = f->readSint16LE(); t.tm_year = f->readSint16LE(); resetAllVariables(); Common::Serializer sz(f, NULL); synchronize(sz); delete f; _isLoaded = true; _animationsEnabled = false; if (_holdTheDawn) { _holdTheDawn = false; fadeIn(); } _background->release(); minorRedraw(); _dropdown->setup(); setRoom(kPeopleAvalot, _room); _alive = true; refreshObjectList(); _animation->updateSpeed(); drawDirection(); _animation->animLink(); _background->update(); Common::String tmpStr = Common::String::format("%cLoaded: %c%s.ASG%c%c%c%s%c%csaved on %s.", kControlItalic, kControlRoman, description.c_str(), kControlCenter, kControlNewLine, kControlNewLine, _roomnName.c_str(), kControlNewLine, kControlNewLine, expandDate(t.tm_mday, t.tm_mon, t.tm_year).c_str()); _dialogs->displayText(tmpStr); AnimationType *avvy = _animation->_sprites[0]; if (avvy->_quick && avvy->_visible) _animation->setMoveSpeed(0, _animation->getDirection()); // We push Avvy in the right direction is he was moving. return true; }