// Load game void SaveLoad::loadGame(GameId id) { // Rewind current savegame _savegame->seek(0); // Validate main header SavegameMainHeader header; if (!loadMainHeader(_savegame, &header)) { debugC(2, kLastExpressDebugSavegame, "SaveLoad::saveGame - Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str()); return; } // Load the last entry _savegame->seek(header.offsetEntry); SavegameType type = kSavegameTypeIndex; EntityIndex entity = kEntityPlayer; uint32 val = 0; readEntry(&type, &entity, &val, header.keepIndex == 1); // Setup last loading time _gameTicksLastSavegame = getState()->timeTicks; if (header.keepIndex) { getSound()->clearQueue(); readEntry(&type, &entity, &val, false); } getEntities()->reset(); getEntities()->setup(false, entity); }
// Check if the game has been started in the specific savegame bool SaveLoad::isSavegameValid(GameId id) { if (!isSavegamePresent(id)) { debugC(2, kLastExpressDebugSavegame, "SaveLoad::isSavegameValid - Savegame does not exist: %s", getFilename(id).c_str()); return false; } SavegameMainHeader header; Common::InSaveFile *save = openForLoading(id); bool isHeaderValid = loadMainHeader(save, &header); delete save; return isHeaderValid; }
// Save game void SaveLoad::saveGame(SavegameType type, EntityIndex entity, uint32 value) { if (getState()->scene <= kSceneIntro) return; // Validate main header SavegameMainHeader header; if (!loadMainHeader(_savegame, &header)) { debugC(2, kLastExpressDebugSavegame, "SaveLoad::saveGame - Cannot load main header: %s", getFilename(getMenu()->getGameId()).c_str()); return; } if (!_savegame) error("SaveLoad::saveGame: savegame stream is invalid"); // Validate the current entry if it exists if (header.count > 0) { _savegame->seek(header.offsetEntry); // Load entry header SavegameEntryHeader entry; Common::Serializer ser(_savegame, NULL); entry.saveLoadWithSerializer(ser); if (!entry.isValid()) { warning("SaveLoad::saveGame: Invalid entry. This savegame might be corrupted!"); _savegame->seek(header.offset); } else if (getState()->time < entry.time || (type == kSavegameTypeTickInterval && getState()->time == entry.time)) { // Not ready to save a game, skipping! return; } else if ((type == kSavegameTypeTime || type == kSavegameTypeEvent) && (entry.type == kSavegameTypeTickInterval && (getState()->time - entry.time) < 450)) { _savegame->seek(header.offsetEntry); --header.count; } else { _savegame->seek(header.offset); } } else { // Seek to the next savegame entry _savegame->seek(header.offset); } if (type != kSavegameTypeEvent2 && type != kSavegameTypeAuto) header.offsetEntry = (uint32)_savegame->pos(); // Write the savegame entry writeEntry(type, entity, value); if (!header.keepIndex) ++header.count; if (type == kSavegameTypeEvent2 || type == kSavegameTypeAuto) { header.keepIndex = 1; } else { header.keepIndex = 0; header.offset = (uint32)_savegame->pos(); // Save ticks _gameTicksLastSavegame = getState()->timeTicks; } // Validate the main header if (!header.isValid()) error("SaveLoad::saveGame: main game header is invalid!"); // Write the main header _savegame->seek(0); Common::Serializer ser(NULL, _savegame); header.saveLoadWithSerializer(ser); flushStream(getMenu()->getGameId()); }