//------------------------------------------------------------------------- /* Copyright (C) 2010-2019 EDuke32 developers and contributors Copyright (C) 2019 sirlemonhead, Nuke.YKT This file is part of PCExhumed. PCExhumed is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //------------------------------------------------------------------------- #include "ns.h" #include "save.h" #include #include #include "init.h" #include "music/z_music.h" //#include //#include //#include #include "engine.h" #include "exhumed.h" #include "mmulti.h" #include "savegamehelp.h" BEGIN_PS_NS extern int MenuExitCondition; void SaveTextureState(); void LoadTextureState(); static TArray sghelpers(TArray::NoInit); bool GameInterface::SaveGame(FSaveGameNode* sv) { OpenSaveGameForWrite(sv->Filename); // workaround until the level info here has been transitioned. G_WriteSaveHeader(sv->SaveTitle); auto fw = WriteSavegameChunk("engine"); fw->Write(&numsectors, sizeof(numsectors)); fw->Write(sector, sizeof(sectortype) * numsectors); fw->Write(&numwalls, sizeof(numwalls)); fw->Write(wall, sizeof(walltype) * numwalls); fw->Write(sprite, sizeof(spritetype) * kMaxSprites); fw->Write(headspritesect, sizeof(headspritesect)); fw->Write(prevspritesect, sizeof(prevspritesect)); fw->Write(nextspritesect, sizeof(nextspritesect)); fw->Write(headspritestat, sizeof(headspritestat)); fw->Write(prevspritestat, sizeof(prevspritestat)); fw->Write(nextspritestat, sizeof(nextspritestat)); fw->Write(&tailspritefree, sizeof(tailspritefree)); fw->Write(&myconnectindex, sizeof(myconnectindex)); fw->Write(&connecthead, sizeof(connecthead)); fw->Write(connectpoint2, sizeof(connectpoint2)); fw->Write(&numframes, sizeof(numframes)); fw->Write(&randomseed, sizeof(randomseed)); fw->Write(&numshades, sizeof(numshades)); fw->Write(&g_visibility, sizeof(g_visibility)); fw->Write(¶llaxtype, sizeof(parallaxtype)); fw->Write(¶llaxyoffs_override, sizeof(parallaxyoffs_override)); fw->Write(¶llaxyscale_override, sizeof(parallaxyscale_override)); fw->Write(&pskybits_override, sizeof(pskybits_override)); fw->Write(show2dwall, sizeof(show2dwall)); fw->Write(show2dsprite, sizeof(show2dsprite)); fw->Write(show2dsector, sizeof(show2dsector)); for (auto sgh : sghelpers) sgh->Save(); SaveTextureState(); FinishSavegameWrite(); return 1; // CHECKME } bool GameInterface::LoadGame(FSaveGameNode* sv) { OpenSaveGameForRead(sv->Filename); auto fr = ReadSavegameChunk("engine"); if (fr.isOpen()) { fr.Read(&numsectors, sizeof(numsectors)); fr.Read(sector, sizeof(sectortype) * numsectors); fr.Read(&numwalls, sizeof(numwalls)); fr.Read(wall, sizeof(walltype) * numwalls); fr.Read(sprite, sizeof(spritetype) * kMaxSprites); fr.Read(headspritesect, sizeof(headspritesect)); fr.Read(prevspritesect, sizeof(prevspritesect)); fr.Read(nextspritesect, sizeof(nextspritesect)); fr.Read(headspritestat, sizeof(headspritestat)); fr.Read(prevspritestat, sizeof(prevspritestat)); fr.Read(nextspritestat, sizeof(nextspritestat)); fr.Read(&tailspritefree, sizeof(tailspritefree)); fr.Read(&myconnectindex, sizeof(myconnectindex)); fr.Read(&connecthead, sizeof(connecthead)); fr.Read(connectpoint2, sizeof(connectpoint2)); fr.Read(&numframes, sizeof(numframes)); fr.Read(&randomseed, sizeof(randomseed)); fr.Read(&numshades, sizeof(numshades)); fr.Read(&g_visibility, sizeof(g_visibility)); fr.Read(¶llaxtype, sizeof(parallaxtype)); fr.Read(¶llaxyoffs_override, sizeof(parallaxyoffs_override)); fr.Read(¶llaxyscale_override, sizeof(parallaxyscale_override)); fr.Read(&pskybits_override, sizeof(pskybits_override)); fr.Read(show2dwall, sizeof(show2dwall)); fr.Read(show2dsprite, sizeof(show2dsprite)); fr.Read(show2dsector, sizeof(show2dsector)); fr.Close(); } for (auto sgh : sghelpers) sgh->Load(); LoadTextureState(); FinishSavegameRead(); // reset the sky in case it hasn't been done yet. psky_t* pSky = tileSetupSky(0); pSky->tileofs[0] = 0; pSky->tileofs[1] = 0; pSky->tileofs[2] = 0; pSky->tileofs[3] = 0; pSky->yoffs = 256; pSky->lognumtiles = 2; pSky->horizfrac = 65536; pSky->yscale = 65536; parallaxtype = 2; g_visibility = 2048; ototalclock = totalclock; MenuExitCondition = 6; Mus_ResumeSaved(); return 1; // CHECKME } SavegameHelper::SavegameHelper(const char* name, ...) { Name = name; sghelpers.Push(this); va_list ap; va_start(ap, name); for(;;) { void* addr = va_arg(ap, void*); if (!addr) break; size_t size = va_arg(ap, size_t); Elements.Push(std::make_pair(addr, size)); } } void SavegameHelper::Load() { auto fr = ReadSavegameChunk(Name); for (auto& entry : Elements) { auto read = fr.Read(entry.first, entry.second); if (read != entry.second) I_Error("Save game read error in %s", Name.GetChars()); } } void SavegameHelper::Save() { auto fw = WriteSavegameChunk(Name); for (auto& entry : Elements) { auto write = fw->Write(entry.first, entry.second); if (write != entry.second) I_Error("Save game write error in %s", Name.GetChars()); } } END_PS_NS