void FSavegameManager::DoSave(int Selected, const char *savegamestring) { if (Selected != 0) { auto node = SaveGames[Selected]; G_SaveGame(node->Filename.GetChars(), savegamestring); } else { // Find an unused filename and save as that FString filename; int i; for (i = 0;; ++i) { filename = G_BuildSaveName("save", i); if (!FileExists(filename)) { break; } } G_SaveGame(filename, savegamestring); } M_ClearMenus(); }
// // M_ReadSaveStrings // read the strings from the savegame files // void M_ReadSaveStrings(void) { FILE *handle; int count; int i; for (i = 0; i < load_end; i++) { std::string name; G_BuildSaveName (name, i); handle = fopen (name.c_str(), "rb"); if (handle == NULL) { strcpy (&savegamestrings[i][0], GStrings(EMPTYSTRING)); LoadMenu[i].status = 0; } else { count = fread (&savegamestrings[i], SAVESTRINGSIZE, 1, handle); fclose (handle); LoadMenu[i].status = 1; } } }
// // User wants to load this game // void M_LoadSelect (int choice) { std::string name; G_BuildSaveName (name, choice); G_LoadGame ((char *)name.c_str()); gamestate = gamestate == GS_FULLCONSOLE ? GS_HIDECONSOLE : gamestate; M_ClearMenus (); if (quickSaveSlot == -2) { quickSaveSlot = choice; } }
void FSavegameManager::ReadSaveStrings() { if (SaveGames.Size() == 0) { void *filefirst; findstate_t c_file; FString filter; LastSaved = LastAccessed = -1; quickSaveSlot = nullptr; filter = G_BuildSaveName("*." SAVEGAME_EXT, -1); filefirst = I_FindFirst(filter.GetChars(), &c_file); if (filefirst != ((void *)(-1))) { do { // I_FindName only returns the file's name and not its full path FString filepath = G_BuildSaveName(I_FindName(&c_file), -1); FResourceFile *savegame = FResourceFile::OpenResourceFile(filepath, true, true); if (savegame != nullptr) { bool oldVer = false; bool missing = false; FResourceLump *info = savegame->FindLump("info.json"); if (info == nullptr) { // savegame info not found. This is not a savegame so leave it alone. delete savegame; continue; } void *data = info->CacheLump(); FSerializer arc(nullptr); if (arc.OpenReader((const char *)data, info->LumpSize)) { int savever = 0; arc("Save Version", savever); FString engine = arc.GetString("Engine"); FString iwad = arc.GetString("Game WAD"); FString title = arc.GetString("Title"); if (engine.Compare(GAMESIG) != 0 || savever > SAVEVER) { // different engine or newer version: // not our business. Leave it alone. delete savegame; continue; } if (savever < MINSAVEVER) { // old, incompatible savegame. List as not usable. oldVer = true; } else if (iwad.CompareNoCase(Wads.GetWadName(Wads.GetIwadNum())) == 0) { missing = !G_CheckSaveGameWads(arc, false); } else { // different game. Skip this. delete savegame; continue; } FSaveGameNode *node = new FSaveGameNode; node->Filename = filepath; node->bOldVersion = oldVer; node->bMissingWads = missing; node->SaveTitle = title; InsertSaveNode(node); delete savegame; } } else // check for old formats. { FileReader file; if (file.OpenFile(filepath)) { PNGHandle *png; char sig[16]; char title[OLDSAVESTRINGSIZE + 1]; bool oldVer = true; bool addIt = false; bool missing = false; // ZDoom 1.23 betas 21-33 have the savesig first. // Earlier versions have the savesig second. // Later versions have the savegame encapsulated inside a PNG. // // Old savegame versions are always added to the menu so // the user can easily delete them if desired. title[OLDSAVESTRINGSIZE] = 0; if (nullptr != (png = M_VerifyPNG(file))) { char *ver = M_GetPNGText(png, "ZDoom Save Version"); if (ver != nullptr) { // An old version if (!M_GetPNGText(png, "Title", title, OLDSAVESTRINGSIZE)) { strncpy(title, I_FindName(&c_file), OLDSAVESTRINGSIZE); } addIt = true; delete[] ver; } delete png; } else { file.Seek(0, FileReader::SeekSet); if (file.Read(sig, 16) == 16) { if (strncmp(sig, "ZDOOMSAVE", 9) == 0) { if (file.Read(title, OLDSAVESTRINGSIZE) == OLDSAVESTRINGSIZE) { addIt = true; } } else { memcpy(title, sig, 16); if (file.Read(title + 16, OLDSAVESTRINGSIZE - 16) == OLDSAVESTRINGSIZE - 16 && file.Read(sig, 16) == 16 && strncmp(sig, "ZDOOMSAVE", 9) == 0) { addIt = true; } } } } if (addIt) { FSaveGameNode *node = new FSaveGameNode; node->Filename = filepath; node->bOldVersion = true; node->bMissingWads = false; node->SaveTitle = title; InsertSaveNode(node); } } } } while (I_FindNext(filefirst, &c_file) == 0); I_FindClose(filefirst); } } }