void Game::loadGame(int slotNumber) { _saveFile = g_system->getSavefileManager()->openForLoading( _vm->generateSaveName(slotNumber)); Common::Serializer s(_saveFile, nullptr); // Load the savaegame header MADSSavegameHeader header; if (!readSavegameHeader(_saveFile, header)) error("Invalid savegame"); if (header._thumbnail) { header._thumbnail->free(); delete header._thumbnail; } // Load most of the savegame data with the exception of scene specific info synchronize(s, true); // Set up section/scene and other initial states for post-load _currentSectionNumber = -2; _scene._currentSceneId = -2; _sectionNumber = _scene._nextSceneId / 100; _scene._frameStartTime = _vm->_events->getFrameCounter(); _vm->_screen._shakeCountdown = -1; // Default the selected inventory item to the first one, if the player has any _scene._userInterface._selectedInvIndex = _objects._inventoryList.size() > 0 ? 0 : -1; // Set player sprites sets flags _player._spritesLoaded = false; _player._spritesChanged = true; }
SaveStateList CProjectItem::getSavegameList(const Common::String &target) { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); Common::StringArray filenames; Common::String saveDesc; Common::String pattern = Common::String::format("%s.0??", target.c_str()); TitanicSavegameHeader header; filenames = saveFileMan->listSavefiles(pattern); sort(filenames.begin(), filenames.end()); // Sort to get the files in numerical order SaveStateList saveList; for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { const char *ext = strrchr(file->c_str(), '.'); int slot = ext ? atoi(ext + 1) : -1; if (slot >= 0 && slot < MAX_SAVEGAME_SLOTS) { Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { SimpleFile f; f.open(in); if (!readSavegameHeader(&f, header)) continue; saveList.push_back(SaveStateDescriptor(slot, header._saveName)); header._thumbnail->free(); delete header._thumbnail; delete in; } } } return saveList; }
Common::Error SavesManager::loadGameState(int slot) { Combat &combat = *g_vm->_combat; EventsManager &events = *g_vm->_events; FileManager &files = *g_vm->_files; Map &map = *g_vm->_map; Party &party = *g_vm->_party; Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( generateSaveName(slot)); if (!saveFile) return Common::kReadingFailed; // Load the savaegame header XeenSavegameHeader header; if (!readSavegameHeader(saveFile, header)) error("Invalid savegame"); // Set the total play time events.setPlayTime(header._totalFrames); // Loop through loading the sides' save archives SaveArchive *archives[2] = { File::_xeenSave, File::_darkSave }; for (int idx = 0; idx < 2; ++idx) { uint fileSize = saveFile->readUint32LE(); if (archives[idx]) { if (fileSize) { Common::SeekableSubReadStream arcStream(saveFile, saveFile->pos(), saveFile->pos() + fileSize); archives[idx]->load(arcStream); } else { archives[idx]->reset((idx == 1) ? File::_darkCc : File::_xeenCc); } } else { assert(!fileSize); } } // Read in miscellaneous files.load(*saveFile); // Load the character roster and party File::_currentSave->loadParty(); // Reset any combat information from the previous game combat.reset(); party._treasure.reset(); // Load the new map map.clearMaze(); map._loadCcNum = files._ccNum; map.load(party._mazeId); delete saveFile; return Common::kNoError; }
WARN_UNUSED_RESULT bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header, bool skipThumbnail) { // Try and open the save file for reading Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading( _vm->generateSaveName(slot)); if (!savefile) return false; bool result = readSavegameHeader(savefile, header, skipThumbnail); delete savefile; return result; }
void CProjectItem::loadGame(int slotId) { CompressedFile file; // Clear any existing project contents and call preload code preLoad(); clear(); // Open either an existing savegame slot or the new game template if (slotId >= 0) { Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( g_vm->generateSaveName(slotId)); file.open(saveFile); } else { Common::File *newFile = new Common::File(); if (!newFile->open("newgame.st")) error("Could not open newgame.st"); file.open(newFile); } // Load the savegame header in TitanicSavegameHeader header; readSavegameHeader(&file, header); delete header._thumbnail; // Load the contents in CProjectItem *newProject = loadData(&file); file.IsClassStart(); getGameManager()->load(&file); file.close(); // Clear existing project clear(); // Detach each item under the loaded project, and re-attach them // to the existing project instance (this) CTreeItem *item; while ((item = newProject->getFirstChild()) != nullptr) { item->detach(); item->addUnder(this); } // Loaded project instance is no longer needed newProject->destroyAll(); // Post-load processing postLoad(); }
bool CGE2Engine::loadGame(int slotNumber) { Common::MemoryReadStream *readStream; // Open up the savegame file Common::String slotName = generateSaveName(slotNumber); Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(slotName); // Read the data into a data buffer int size = saveFile->size(); byte *dataBuffer = (byte *)malloc(size); saveFile->read(dataBuffer, size); readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES); delete saveFile; // Check to see if it's a ScummVM savegame or not char buffer[kSavegameStrSize + 1]; readStream->read(buffer, kSavegameStrSize + 1); if (strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) != 0) { delete readStream; return false; } else { SavegameHeader saveHeader; if (!readSavegameHeader(readStream, saveHeader)) { delete readStream; return false; } // Delete the thumbnail saveHeader.thumbnail->free(); delete saveHeader.thumbnail; } resetGame(); // Get in the savegame syncGame(readStream, nullptr); delete readStream; loadHeroes(); return true; }
Common::Error loadSavegameData(int saveGameIdx, DraciEngine *vm) { Common::String saveName; Common::SaveFileManager *saveMan = g_system->getSavefileManager(); Common::InSaveFile *f = saveMan->openForLoading(vm->getSavegameFile(saveGameIdx)); if (f == NULL) { return Common::kNoGameDataFoundError; } // Skip over the savegame header DraciSavegameHeader header; if (!readSavegameHeader(f, header)) { return Common::kNoGameDataFoundError; } if (header.thumbnail) { header.thumbnail->free(); delete header.thumbnail; } // Pre-processing vm->_game->rememberRoomNumAsPrevious(); vm->_game->deleteObjectAnimations(); // Synchronise the remaining data of the savegame Common::Serializer s(f, NULL); vm->_game->DoSync(s); delete f; // Post-processing vm->_game->scheduleEnteringRoomUsingGate(vm->_game->getRoomNum(), 0); vm->_game->setExitLoop(true); vm->_game->setIsReloaded(true); vm->_game->inventoryReload(); vm->setTotalPlayTime(header.playtime * 1000); return Common::kNoError; }
Common::Error SaveLoadManager::loadGame(int slot) { // Try and open the save file for reading Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading( _vm->generateSaveName(slot)); if (!savefile) return Common::kReadingFailed; // Set up the serializer Common::Serializer serializer(savefile, NULL); // Read in the savegame header hopkinsSavegameHeader header; if (!readSavegameHeader(savefile, header)) { delete savefile; return Common::kReadingFailed; } // Read in the savegame data syncSavegameData(serializer, header._version); // Loading save file complete delete savefile; // Unpack the inventory for (int i = 0; i < 35; ++i) _vm->_globals->_inventory[i] = _vm->_globals->_saveData->_inventory[i]; // Set variables from loaded data as necessary _vm->_globals->_saveData->_data[svLastSavegameSlot] = slot; _vm->_globals->_exitId = _vm->_globals->_saveData->_data[svLastScreenId]; _vm->_globals->_saveData->_data[svLastPrevScreenId] = 0; _vm->_globals->_screenId = 0; _vm->_objectsMan->_mapCarPosX = _vm->_globals->_saveData->_mapCarPosX; _vm->_objectsMan->_mapCarPosY = _vm->_globals->_saveData->_mapCarPosY; return Common::kNoError; }
Common::Error XeenEngine::loadGameState(int slot) { Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( generateSaveName(slot)); if (!saveFile) return Common::kReadingFailed; Common::Serializer s(saveFile, nullptr); // Load the savaegame header XeenSavegameHeader header; if (!readSavegameHeader(saveFile, header)) error("Invalid savegame"); if (header._thumbnail) { header._thumbnail->free(); delete header._thumbnail; } // Load most of the savegame data synchronize(s); delete saveFile; return Common::kNoError; }
bool CGEEngine::loadGame(int slotNumber, SavegameHeader *header, bool tiny) { debugC(1, kCGEDebugEngine, "CGEEngine::loadgame(%d, header, %s)", slotNumber, tiny ? "true" : "false"); Common::MemoryReadStream *readStream; SavegameHeader saveHeader; if (slotNumber == -1) { // Loading the data for the initial game state EncryptedStream file = EncryptedStream(this, kSavegame0Name); int size = file.size(); byte *dataBuffer = (byte *)malloc(size); file.read(dataBuffer, size); readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES); } else { // Open up the savegame file Common::String slotName = generateSaveName(slotNumber); Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(slotName); // Read the data into a data buffer int size = saveFile->size(); byte *dataBuffer = (byte *)malloc(size); saveFile->read(dataBuffer, size); readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES); delete saveFile; } // Check to see if it's a ScummVM savegame or not char buffer[kSavegameStrSize + 1]; readStream->read(buffer, kSavegameStrSize + 1); if (strncmp(buffer, savegameStr, kSavegameStrSize + 1) != 0) { // It's not, so rewind back to the start readStream->seek(0); if (header) // Header wanted where none exists, so return false return false; } else { // Found header if (!readSavegameHeader(readStream, saveHeader)) { delete readStream; return false; } if (header) { *header = saveHeader; delete readStream; return true; } // Delete the thumbnail saveHeader.thumbnail->free(); delete saveHeader.thumbnail; } // Get in the savegame syncGame(readStream, NULL, tiny); delete readStream; return true; }
Common::Error Saver::restore(int slot) { assert(!getMacroRestoreFlag()); Common::StackLock slock1(g_globals->_soundManager._serverDisabledMutex); // Signal any objects registered for notification _loadNotifiers.notify(false); // Set fields _macroRestoreFlag = true; _unresolvedPtrs.clear(); // Set up the serializer Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(g_vm->generateSaveName(slot)); if (!saveFile) return Common::kReadingFailed; Serializer serializer(saveFile, NULL); // Read in the savegame header tSageSavegameHeader header; readSavegameHeader(saveFile, header); if (header.thumbnail) header.thumbnail->free(); delete header.thumbnail; serializer.setSaveVersion(header.version); // Load in data for objects that need to come at the start of the savegame for (Common::List<SaveListener *>::iterator i = _listeners.begin(); i != _listeners.end(); ++i) { (*i)->listenerSynchronize(serializer); } // Loop through each registered object to load in the data for (SynchronizedList<SavedObject *>::iterator i = _objList.begin(); i != _objList.end(); ++i) { serializer.validate((*i)->getClassName()); (*i)->synchronize(serializer); } // Loop through the remaining data of the file, instantiating new objects. // Note: I don't store pointers to instantiated objects here, because it's not necessary - the mere act // of instantiating a saved object registers it with the saver, and will then be resolved to whatever // object originally had a pointer to it as part of the post-processing step Common::String className; serializer.syncString(className); while (className != "END") { SavedObject *savedObject; if (!_factoryPtr || ((savedObject = _factoryPtr(className)) == NULL)) error("Unknown class name '%s' encountered trying to restore savegame", className.c_str()); // Populate the contents of the object savedObject->synchronize(serializer); // Move to next object serializer.syncString(className); } // Post-process any unresolved pointers to get the correct pointer resolveLoadPointers(); delete saveFile; // Final post-restore notifications _macroRestoreFlag = false; _loadNotifiers.notify(true); return Common::kNoError; }
Common::Error loadSavegameData(int saveGameIdx) { int lowMemorySave; Common::String saveName; cellStruct *currentcellHead; Common::SaveFileManager *saveMan = g_system->getSavefileManager(); Common::InSaveFile *f = saveMan->openForLoading(_vm->getSavegameFile(saveGameIdx)); if (f == NULL) { printInfoBlackBox("Savegame not found..."); waitForPlayerInput(); return Common::kNoGameDataFoundError; } printInfoBlackBox("Loading in progress..."); initVars(); _vm->sound().stopMusic(); // Skip over the savegame header CruiseSavegameHeader header; readSavegameHeader(f, header); delete header.thumbnail; // Synchronise the remaining data of the savegame Common::Serializer s(f, NULL); DoSync(s); delete f; // Post processing for (int j = 0; j < 64; j++) preloadData[j].ptr = NULL; for (int j = 1; j < numOfLoadedOverlay; j++) { if (overlayTable[j].alreadyLoaded) { overlayTable[j].alreadyLoaded = 0; loadOverlay(overlayTable[j].overlayName); if (overlayTable[j].alreadyLoaded) { ovlDataStruct *ovlData = overlayTable[j].ovlData; // overlay BSS if (ovlRestoreData[j]._sBssSize) { if (ovlData->data4Ptr) { MemFree(ovlData->data4Ptr); } ovlData->data4Ptr = ovlRestoreData[j]._pBss; ovlData->sizeOfData4 = ovlRestoreData[j]._sBssSize; } // overlay object data if (ovlRestoreData[j]._sNumObj) { if (ovlData->arrayObjVar) { MemFree(ovlData->arrayObjVar); } ovlData->arrayObjVar = ovlRestoreData[j]._pObj; ovlData->size9 = ovlRestoreData[j]._sNumObj; } } } } updateAllScriptsImports(); lastAni[0] = 0; lowMemorySave = lowMemory; for (int i = 0; i < NUM_FILE_ENTRIES; i++) { if (filesDatabase[i].subData.ptr) { int j; int k; for (j = i + 1; j < NUM_FILE_ENTRIES && filesDatabase[j].subData.ptr && !strcmp(filesDatabase[i].subData.name, filesDatabase[j].subData.name) && (filesDatabase[j].subData.index == (j - i)); j++) ; for (k = i; k < j; k++) { if (filesDatabase[k].subData.ptrMask) lowMemory = 0; filesDatabase[k].subData.ptr = NULL; filesDatabase[k].subData.ptrMask = NULL; } /*if (j < 2) { error("Unsupported mono file load"); //loadFileMode1(filesDatabase[j].subData.name,filesDatabase[j].subData.var4); } else */ if (strlen(filesDatabase[i].subData.name) > 0) { loadFileRange(filesDatabase[i].subData.name, filesDatabase[i].subData.index, i, j - i); } else { filesDatabase[i].subData.ptr = NULL; filesDatabase[i].subData.ptrMask = NULL; } i = j - 1; lowMemory = lowMemorySave; } } lastAni[0] = 0; currentcellHead = cellHead.next; while (currentcellHead) { if (currentcellHead->type == 5) { uint8 *ptr = mainProc14(currentcellHead->overlay, currentcellHead->idx); ASSERT(0); if (ptr) { ASSERT(0); //*(int16 *)(currentcellHead->datas+0x2E) = getSprite(ptr,*(int16 *)(currentcellHead->datas+0xE)); } else { ASSERT(0); //*(int16 *)(currentcellHead->datas+0x2E) = 0; } } currentcellHead = currentcellHead->next; } if (strlen(currentCtpName)) { loadCtFromSave = 1; initCt(currentCtpName); loadCtFromSave = 0; } //prepareFadeOut(); //gfxModuleData.gfxFunction8(); for (int j = 0; j < 8; j++) { if (strlen((char *)backgroundTable[j].name)) { loadBackground(backgroundTable[j].name, j); } } regenerateBackgroundIncrust(&backgroundIncrustHead); // to finish changeCursor(CURSOR_NORMAL); mainDraw(1); flipScreen(); return Common::kNoError; }