- Blood: Savegame fully transitioned to JSON

not tested yet.
This commit is contained in:
Christoph Oelckers 2020-11-22 16:47:08 +01:00
parent 572d3c9944
commit 9a4073508d
29 changed files with 763 additions and 912 deletions

View file

@ -46,7 +46,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gib.h"
#include "globals.h"
#include "levels.h"
#include "loadsave.h"
#include "player.h"
#include "seq.h"
#include "sound.h"

View file

@ -41,7 +41,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gib.h"
#include "globals.h"
#include "levels.h"
#include "loadsave.h"
#include "player.h"
#include "seq.h"
#include "sound.h"
@ -1773,56 +1772,13 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, DUDEEXTRA& w, DUDE
//
//---------------------------------------------------------------------------
FSerializer& Serialize(FSerializer& arc, const char* keyname, GENDUDEEXTRA& w, GENDUDEEXTRA* def)
{
if (arc.BeginObject(keyname))
{
arc.Array("initvals", w.initVals, 3)
.Array("availdeaths", w.availDeaths, kDamageMax)
("movespeed", w.moveSpeed)
("firedist", w.fireDist)
("throwdist", w.throwDist)
("curweapon", w.curWeapon)
("weapontype", w.weaponType)
("basedispersion", w.baseDispersion)
("slavecount", w.slaveCount)
("lifeleech", w.nLifeLeech)
.Array("slaves", w.slave, w.slaveCount)
.Array("dmgcontrol", w.dmgControl, kDamageMax)
.Array("updreq", w.updReq, kGenDudePropertyMax)
("flags", w.flags)
.EndObject();
}
return arc;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void SerializeAI(FSerializer& arc)
{
if (arc.BeginObject("ai"))
{
arc.SparseArray("dudeslope", gDudeSlope, kMaxSprites, activeXSprites)
.SparseArray("dudeextra", gDudeExtra, kMaxSprites, activeXSprites);
// the GenDudeArray only contains valid info for kDudeModernCustom and kDudeModernCustomBurning so only save the relevant entries as these are not small.
bool foundsome = false;
for (int i = 0; i < kMaxSprites; i++)
{
if (activeSprites[i] && (sprite[i].type == kDudeModernCustom || sprite[i].type == kDudeModernCustomBurning))
{
if (!foundsome) arc.BeginArray("gendudeextra");
foundsome = true;
arc(nullptr, gGenDudeExtra[i]);
}
}
if (foundsome) arc.EndArray();
arc.EndObject();
.SparseArray("dudeextra", gDudeExtra, kMaxSprites, activeXSprites)
.EndObject();
}
}

View file

@ -33,7 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "endgame.h"
#include "aistate.h"
#include "loadsave.h"
#include "sectorfx.h"
#include "choke.h"
#include "view.h"

View file

@ -31,7 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "db.h"
#include "player.h"
#include "sound.h"
#include "loadsave.h"
#include "raze_sound.h"
BEGIN_BLD_NS

View file

@ -40,7 +40,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gib.h"
#include "globals.h"
#include "levels.h"
#include "loadsave.h"
#include "sectorfx.h"
#include "seq.h"
#include "sound.h"
@ -502,7 +501,6 @@ void GameInterface::app_init()
FireInit();
Printf(PRINT_NONOTIFY, "Initializing weapon animations\n");
WeaponInit();
LoadSaveSetup();
myconnectindex = connecthead = 0;
gNetPlayers = numplayers = 1;

View file

@ -82,8 +82,6 @@ struct GameInterface : ::GameInterface
void MenuClosed() override;
bool CanSave() override;
bool StartGame(FNewGameStartup& gs) override;
bool SaveGame() override;
bool LoadGame() override;
void QuitToTitle() override;
FString GetCoordString() override;
ReservedSpace GetReservedScreenSpace(int viewsize) override;

View file

@ -463,13 +463,8 @@ struct LOCATION {
int ang;
};
struct POINT2D {
int x, y;
};
struct POINT3D {
int x, y, z;
};
using POINT2D = vec2_t;
using POINT3D = vec3_t;
struct VECTOR2D {
int dx, dy;

View file

@ -47,6 +47,9 @@ XSPRITE xsprite[kMaxXSprites];
XSECTOR xsector[kMaxXSectors];
XWALL xwall[kMaxXWalls];
XSECTOR xsectorbackup[kMaxXSectors];
XWALL xwallbackup[kMaxXWalls];
SPRITEHIT gSpriteHit[kMaxXSprites];
int xvel[kMaxSprites], yvel[kMaxSprites], zvel[kMaxSprites];
@ -274,6 +277,20 @@ void InitFreeList(unsigned short *pList, int nCount)
pList[0] = nCount - 1;
}
void InitFreeList(unsigned short* pList, int nCount, FixedBitArray<MAXSPRITES>&used)
{
int lastfree = 0;
for (int i = 1; i < nCount; i++)
{
if (!used[i])
{
pList[i] = lastfree;
lastfree = i;
}
}
pList[0] = lastfree;
}
void InsertFree(unsigned short *pList, int nIndex)
{
pList[nIndex] = pList[0];
@ -391,14 +408,13 @@ void PropagateMarkerReferences(void)
}
}
bool byte_1A76C6, byte_1A76C7, byte_1A76C8;
bool drawtile2048, encrypted;
MAPHEADER2 byte_19AE44;
unsigned int dbReadMapCRC(const char *pPath)
{
byte_1A76C7 = 0;
byte_1A76C8 = 0;
encrypted = 0;
FString mapname = pPath;
DefaultExtension(mapname, ".map");
@ -422,7 +438,7 @@ unsigned int dbReadMapCRC(const char *pPath)
}
else if ((ver & 0xff00) == 0x700)
{
byte_1A76C8 = 1;
encrypted = 1;
}
else
{
@ -432,7 +448,7 @@ unsigned int dbReadMapCRC(const char *pPath)
return fr.ReadInt32();
}
int gMapRev, gSongId, gSkyCount;
int gMapRev, gMattId, gSkyCount;
//char byte_19AE44[128];
const int nXSectorSize = 60;
const int nXSpriteSize = 56;
@ -517,9 +533,9 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
{
I_Error("%s: Map file corrupted", mapname.GetChars());
}
byte_1A76C8 = 0;
encrypted = 0;
if ((LittleShort(header.version) & 0xff00) == 0x700) {
byte_1A76C8 = 1;
encrypted = 1;
#ifdef NOONE_EXTENSIONS
// indicate if the map requires modern features to work properly
@ -536,7 +552,6 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
fr.Read(&mapHeader,37/* sizeof(mapHeader)*/);
if (mapHeader.mattid != 0 && mapHeader.mattid != 0x7474614d && mapHeader.mattid != 0x4d617474) {
dbCrypt((char*)&mapHeader, sizeof(mapHeader), 0x7474614d);
byte_1A76C7 = 1;
}
mapHeader.x = LittleLong(mapHeader.x);
@ -558,16 +573,16 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
*pAngle = mapHeader.ang;
*pSector = mapHeader.sect;
gVisibility = g_visibility = mapHeader.visibility;
gSongId = mapHeader.mattid;
if (byte_1A76C8)
gMattId = mapHeader.mattid;
if (encrypted)
{
if (mapHeader.mattid == 0x7474614d || mapHeader.mattid == 0x4d617474)
{
byte_1A76C6 = 1;
drawtile2048 = 1;
}
else if (!mapHeader.mattid)
{
byte_1A76C6 = 0;
drawtile2048 = 0;
}
else
{
@ -583,7 +598,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
numsectors = mapHeader.numsectors;
numwalls = mapHeader.numwalls;
dbInit();
if (byte_1A76C8)
if (encrypted)
{
fr.Read(&byte_19AE44, 128);
dbCrypt((char*)&byte_19AE44, 128, numwalls);
@ -598,7 +613,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
}
gSkyCount = 1<< mapHeader.pskybits;
fr.Read(tpskyoff, gSkyCount*sizeof(tpskyoff[0]));
if (byte_1A76C8)
if (encrypted)
{
dbCrypt((char*)tpskyoff, gSkyCount*sizeof(tpskyoff[0]), gSkyCount*2);
}
@ -616,7 +631,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
sectortype *pSector = &sector[i];
sectortypedisk load;
fr.Read(&load, sizeof(sectortypedisk));
if (byte_1A76C8)
if (encrypted)
{
dbCrypt((char*)&load, sizeof(sectortypedisk), gMapRev*sizeof(sectortypedisk));
}
@ -652,7 +667,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
XSECTOR *pXSector = &xsector[nXSector];
memset(pXSector, 0, sizeof(XSECTOR));
int nCount;
if (!byte_1A76C8)
if (!encrypted)
{
nCount = nXSectorSize;
}
@ -750,7 +765,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
walltype *pWall = &wall[i];
walltypedisk load;
fr.Read(&load, sizeof(walltypedisk));
if (byte_1A76C8)
if (encrypted)
{
dbCrypt((char*)&load, sizeof(walltypedisk), (gMapRev*sizeof(sectortypedisk)) | 0x7474614d);
}
@ -779,7 +794,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
XWALL *pXWall = &xwall[nXWall];
memset(pXWall, 0, sizeof(XWALL));
int nCount;
if (!byte_1A76C8)
if (!encrypted)
{
nCount = nXWallSize;
}
@ -833,7 +848,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
spritetypedisk load;
spritetype *pSprite = &sprite[i];
fr.Read(&load, sizeof(spritetypedisk)); // load into an intermediate buffer so that spritetype is no longer bound by file formats.
if (byte_1A76C8) // What were these people thinking? :(
if (encrypted) // What were these people thinking? :(
{
dbCrypt((char*)&load, sizeof(spritetypedisk), (gMapRev*sizeof(spritetypedisk)) | 0x7474614d);
}
@ -874,7 +889,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
XSPRITE *pXSprite = &xsprite[nXSprite];
memset(pXSprite, 0, sizeof(XSPRITE));
int nCount;
if (!byte_1A76C8)
if (!encrypted)
{
nCount = nXSpriteSize;
}
@ -948,7 +963,7 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
bitReader.skipBits(32);
xsprite[sprite[i].extra].reference = i;
xsprite[sprite[i].extra].busy = IntToFixed(xsprite[sprite[i].extra].state);
if (!byte_1A76C8) {
if (!encrypted) {
xsprite[sprite[i].extra].lT |= xsprite[sprite[i].extra].lB;
}
@ -978,22 +993,22 @@ void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, shor
if (pCRC)
*pCRC = nCRC;
PropagateMarkerReferences();
if (byte_1A76C8)
if (encrypted)
{
if (gSongId == 0x7474614d || gSongId == 0x4d617474)
if (gMattId == 0x7474614d || gMattId == 0x4d617474)
{
byte_1A76C6 = 1;
drawtile2048 = 1;
}
else if (!gSongId)
else if (!gMattId)
{
byte_1A76C6 = 0;
drawtile2048 = 0;
}
else
{
I_Error("%s: Corrupted Map file", mapname.GetChars());
}
}
else if (gSongId != 0)
else if (gMattId != 0)
{
I_Error("%s: Corrupted Map file", mapname.GetChars());
}

View file

@ -298,13 +298,17 @@ struct SPRITEHIT {
extern unsigned short gStatCount[kMaxStatus + 1];;
extern bool byte_1A76C6, byte_1A76C7, byte_1A76C8;
extern bool drawtile2048, encrypted;
extern MAPHEADER2 byte_19AE44;
extern XSPRITE xsprite[kMaxXSprites];
extern XSECTOR xsector[kMaxXSectors];
extern XWALL xwall[kMaxXWalls];
extern XSECTOR xsectorbackup[kMaxXSectors];
extern XWALL xwallbackup[kMaxXWalls];
extern FixedBitArray<MAXSPRITES> activeXSprites;
extern SPRITEHIT gSpriteHit[kMaxXSprites];
extern char qsector_filler[kMaxSectors];
@ -312,7 +316,7 @@ extern char qsector_filler[kMaxSectors];
extern int xvel[kMaxSprites], yvel[kMaxSprites], zvel[kMaxSprites];
extern int gVisibility;
extern int gMapRev, gSongId, gSkyCount;
extern int gMapRev, gMattId, gSkyCount;
extern const char *gItemText[];
extern const char *gAmmoText[];
extern const char *gWeaponText[];
@ -366,6 +370,7 @@ int qchangespritesect(short nSprite, short nSector);
int ChangeSpriteStat(int nSprite, int nStatus);
int qchangespritestat(short nSprite, short nStatus);
void InitFreeList(unsigned short *pList, int nCount);
void InitFreeList(unsigned short* pList, int nCount, FixedBitArray<MAXSPRITES>& activeXSprites);
void InsertFree(unsigned short *pList, int nIndex);
unsigned short dbInsertXSprite(int nSprite);
void dbDeleteXSprite(int nXSprite);

View file

@ -31,7 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "endgame.h"
#include "globals.h"
#include "levels.h"
#include "loadsave.h"
#include "player.h"
#include "sound.h"
#include "view.h"

View file

@ -33,7 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "endgame.h"
#include "aistate.h"
#include "loadsave.h"
#include "sectorfx.h"
#include "choke.h"
#include "view.h"

View file

@ -32,7 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "endgame.h"
#include "inifile.h"
#include "levels.h"
#include "loadsave.h"
#include "messages.h"
#include "seq.h"
#include "sound.h"
@ -45,7 +44,7 @@ BEGIN_BLD_NS
GAMEOPTIONS gGameOptions;
GAMEOPTIONS gSingleGameOptions = {
0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 3600, 1800, 1800, 7200
0, 2, 0, 0, 0, 0, 0, 0, 2, 3600, 1800, 1800, 7200
};
EPISODEINFO gEpisodeInfo[kMaxEpisodes+1];

View file

@ -49,8 +49,6 @@ enum EGameFlag
struct GAMEOPTIONS {
unsigned char nGameType;
unsigned char nDifficulty;
short nSaveGameSlot;
int picEntry;
char nMonsterSettings;
int uGameFlags;
int uNetGameFlags;

View file

@ -1,13 +1,12 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
Copyright (C) 2020 - Christoph Oelckers
This file is part of NBlood.
This file is part of Raze
NBlood is free software; you can redistribute it and/or
Raze 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.
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -20,6 +19,7 @@ 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" // Must come before everything else!
#include <stdio.h>
@ -32,7 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "globals.h"
#include "db.h"
#include "messages.h"
#include "loadsave.h"
#include "sectorfx.h"
#include "seq.h"
#include "sound.h"
@ -406,337 +405,233 @@ static AISTATE* allAIStates[] =
&zombieFTeslaRecoil,
};
void IndexAIState(AISTATE*& state)
FSerializer& Serialize(FSerializer& arc, const char* keyname, AISTATE*& w, AISTATE** def)
{
int i = 0;
auto savestate = state;
if (arc.isWriting())
{
for (auto cstate : allAIStates)
{
if (state == cstate)
if (w == cstate)
{
state = (AISTATE*)(intptr_t)i;
return;
arc(keyname, i);
break;
}
i++;
}
state = nullptr;
}
void UnindexAIState(AISTATE*& state)
{
auto index = intptr_t(state);
if (index >= 0 && index < countof(allAIStates))
{
state = allAIStates[index];
}
else
{
state = nullptr;
}
}
unsigned int dword_27AA38 = 0;
unsigned int dword_27AA3C = 0;
unsigned int dword_27AA40 = 0;
FileWriter *LoadSave::hSFile = NULL;
FileReader LoadSave::hLFile;
TDeletingArray<LoadSave*> LoadSave::loadSaves;
void sub_76FD4(void)
arc(keyname, i);
if (i >= 0 && i < countof(allAIStates))
{
w = allAIStates[i];
}
void LoadSave::Save(void)
else
{
I_Error("Pure virtual function called");
}
void LoadSave::Load(void)
{
I_Error("Pure virtual function called");
}
void LoadSave::Read(void *pData, int nSize)
{
dword_27AA38 += nSize;
assert(hLFile.isOpen());
if (hLFile.Read(pData, nSize) != nSize)
I_Error("Error reading save file.");
}
void LoadSave::Write(const void *pData, int nSize)
{
dword_27AA38 += nSize;
dword_27AA3C += nSize;
assert(hSFile != NULL);
if (hSFile->Write(pData, nSize) != (size_t)nSize)
I_Error("File error #%d writing save file.", errno);
}
bool GameInterface::LoadGame()
{
LoadSave::hLFile = ReadSavegameChunk("snapshot.bld");
if (!LoadSave::hLFile.isOpen())
return false;
for (auto rover : LoadSave::loadSaves)
{
rover->Load();
}
LoadSave::hLFile.Close();
FinishSavegameRead();
InitSectorFX();
viewInitializePrediction();
PreloadCache();
if (!gMe->packSlots[1].isActive) // if diving suit is not active, turn off reverb sound effect
sfxSetReverb(0);
ambInit();
for (int i = 0; i < gNetPlayers; i++)
playerSetRace(&gPlayer[i], gPlayer[i].lifeMode);
viewSetErrorMessage("");
Net_ClearFifo();
paused = 0;
#ifdef USE_OPENGL
Polymost_prepare_loadboard();
#endif
#ifdef POLYMER
if (videoGetRenderMode() == REND_POLYMER)
polymer_loadboard();
// this light pointer nulling needs to be outside the videoGetRenderMode check
// because we might be loading the savegame using another renderer but
// change to Polymer later
for (int i=0; i<kMaxSprites; i++)
{
gPolymerLight[i].lightptr = NULL;
gPolymerLight[i].lightId = -1;
}
#endif
Mus_ResumeSaved();
return true;
}
bool GameInterface::SaveGame()
{
LoadSave::hSFile = WriteSavegameChunk("snapshot.bld");
try
{
dword_27AA38 = 0;
dword_27AA40 = 0;
for (auto rover : LoadSave::loadSaves)
{
rover->Save();
if (dword_27AA38 > dword_27AA40)
dword_27AA40 = dword_27AA38;
dword_27AA38 = 0;
w = nullptr;
}
}
catch (CRecoverableError & err)
{
// Let's not abort for write errors.
Printf(TEXTCOLOR_RED "%s\n", err.what());
return false;
}
LoadSave::hSFile = NULL;
return 1;
return arc;
}
class MyLoadSave : public LoadSave
FSerializer& Serialize(FSerializer& arc, const char* keyname, XWALL& w, XWALL* def)
{
public:
virtual void Load(void);
virtual void Save(void);
};
if (arc.BeginObject(keyname))
{
arc("flags", w.flags, def->flags)
("busy", w.busy, def->busy)
("reference", w.reference, def->reference)
("data", w.data, def->data)
("txid", w.txID, def->txID)
("rxid", w.rxID, def->rxID)
("busytime", w.busyTime, def->busyTime)
("waittime", w.waitTime, def->waitTime)
("command", w.command, def->command)
("panxvel", w.panXVel, def->panXVel)
("panyvel", w.panYVel, def->panYVel)
("key", w.key, def->key)
("xpanfrac", w.xpanFrac, def->xpanFrac)
("ypanfrac", w.ypanFrac, def->ypanFrac)
.EndObject();
}
return arc;
}
void MyLoadSave::Load(void)
FSerializer& Serialize(FSerializer& arc, const char* keyname, XSECTOR& w, XSECTOR* def)
{
if (arc.BeginObject(keyname))
{
arc("flags", w.flags, def->flags)
("busy", w.busy, def->busy)
("reference", w.reference, def->reference)
("data", w.data, def->data)
("txid", w.txID, def->txID)
("rxid", w.rxID, def->rxID)
("offceilz", w.offCeilZ, def->offCeilZ)
("onceilz", w.onCeilZ, def->onCeilZ)
("offloorz", w.offFloorZ, def->offFloorZ)
("onloorz", w.onFloorZ, def->onFloorZ)
("windvel", w.windVel, def->windVel)
("busytimea", w.busyTimeA, def->busyTimeA)
("busytimeb", w.busyTimeB, def->busyTimeB)
("waittimea", w.waitTimeA, def->waitTimeA)
("waittimeb", w.waitTimeB, def->waitTimeB)
("panangle", w.panAngle, def->panAngle)
("marker0", w.marker0, def->marker0)
("marker1", w.marker1, def->marker1)
("windang", w.windAng, def->windAng)
("bobtheta", w.bobTheta, def->bobTheta)
("bobspeed", w.bobSpeed, def->bobSpeed)
("busywavea", w.busyWaveA, def->busyWaveA)
("busywaveb", w.busyWaveB, def->busyWaveB)
("command", w.command, def->command)
("amplitude", w.amplitude, def->amplitude)
("freq", w.freq, def->freq)
("phase", w.phase, def->phase)
("wave", w.wave, def->wave)
("shade", w.shade, def->shade)
("panvel", w.panVel, def->panVel)
("depth", w.Depth, def->Depth)
("key", w.Key, def->Key)
("ceilpal", w.ceilpal, def->ceilpal)
("ceilxpanfrac", w.ceilXPanFrac, def->ceilXPanFrac)
("ceilypanfrac", w.ceilYPanFrac, def->ceilYPanFrac)
("floorxpanfrac", w.floorXPanFrac, def->floorXPanFrac)
("floorypanfrac", w.floorYPanFrac, def->floorYPanFrac)
("floorpal", w.floorpal, def->floorpal)
("damagetype", w.damageType, def->damageType)
("bobzrange", w.bobZRange, def->bobZRange)
.EndObject();
}
return arc;
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, XSPRITE& w, XSPRITE* def)
{
if (arc.BeginObject(keyname))
{
arc("flags", w.flags, def->flags)
("busy", w.busy, def->busy)
("reference", w.reference, def->reference)
("txid", w.txID, def->txID)
("rxid", w.rxID, def->rxID)
("command", w.command, def->command)
("data1", w.data1, def->data1)
("data2", w.data2, def->data2)
("data3", w.data3, def->data3)
("data4", w.data4, def->data4)
("targetX", w.targetX, def->targetX)
("targetY", w.targetY, def->targetY)
("targetZ", w.targetZ, def->targetZ)
("target", w.target, def->target)
("sysdata1", w.sysData1, def->sysData1)
("sysdata2", w.sysData2, def->sysData2)
("scale", w.scale, def->scale)
("physattr", w.physAttr, def->physAttr)
("health", w.health, def->health)
("burnsource", w.burnSource, def->burnSource)
("busytime", w.busyTime, def->busyTime)
("waittime", w.waitTime, def->waitTime)
("goalang", w.goalAng, def->goalAng)
("burntime", w.burnTime, def->burnTime)
("height", w.height, def->height)
("statetimer", w.stateTimer, def->stateTimer)
("respawnpending", w.respawnPending, def->respawnPending)
("dropmsg", w.dropMsg, def->dropMsg)
("key", w.key, def->key)
("lskill", w.lSkill, def->lSkill)
("lockmsg", w.lockMsg, def->lockMsg)
("dodgedir", w.dodgeDir, def->dodgeDir)
.EndObject();
}
return arc;
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, HITINFO& w, HITINFO* def)
{
if (arc.BeginObject(keyname))
{
arc("sect", w.hitsect)
("sprite", w.hitsprite)
("wall", w.hitwall)
("x", w.hitx)
("y", w.hity)
("z", w.hitz)
.EndObject();
}
return arc;
}
FSerializer& Serialize(FSerializer& arc, const char* keyname, GAMEOPTIONS& w, GAMEOPTIONS* def)
{
if (arc.BeginObject(keyname))
{
arc("type", w.nGameType)
("difficulty", w.nDifficulty)
("monster", w.nMonsterSettings)
("flags", w.uGameFlags)
("netflags", w.uNetGameFlags)
("weapons", w.nWeaponSettings)
("items", w.nItemSettings)
("respawn", w.nRespawnSettings)
("team", w.nTeamSettings)
("monsterrespawntime", w.nMonsterRespawnTime)
("itemrespawntime", w.nItemRespawnTime)
("specialrespawntime", w.nSpecialRespawnTime)
("weaponsv10x", w.weaponsV10x)
("friendlyfire", w.bFriendlyFire)
("keepkeys", w.bKeepKeysOnRespawn)
.EndObject();
}
return arc;
}
void SerializeState(FSerializer& arc)
{
if (arc.isReading())
{
cheatReset();
}
if (arc.BeginObject("state"))
{
psky_t* pSky = tileSetupSky(DEFAULTPSKY);
int id;
Read(&id, sizeof(id));
Read(&gGameOptions, sizeof(gGameOptions));
int nNumSprites;
Read(&nNumSprites, sizeof(nNumSprites));
Read(qsector_filler, sizeof(qsector_filler[0])*numsectors);
Read(&pSky->horizfrac, sizeof(pSky->horizfrac));
Read(&pSky->yoffs, sizeof(pSky->yoffs));
Read(&pSky->yscale, sizeof(pSky->yscale));
Read(&gVisibility, sizeof(gVisibility));
Read(pSky->tileofs, sizeof(pSky->tileofs));
Read(&pSky->lognumtiles, sizeof(pSky->lognumtiles));
Read(gotpic, sizeof(gotpic));
Read(gotsector, sizeof(gotsector));
Read(&gFrameClock, sizeof(gFrameClock));
Read(&gFrameCount, sizeof(gFrameCount));
Read(&paused, sizeof(paused));
Read(baseWall, sizeof(baseWall[0])*numwalls);
Read(baseSprite, sizeof(baseSprite[0])*nNumSprites);
Read(baseFloor, sizeof(baseFloor[0])*numsectors);
Read(baseCeil, sizeof(baseCeil[0])*numsectors);
Read(velFloor, sizeof(velFloor[0])*numsectors);
Read(velCeil, sizeof(velCeil[0])*numsectors);
Read(&gHitInfo, sizeof(gHitInfo));
Read(&byte_1A76C6, sizeof(byte_1A76C6));
Read(&byte_1A76C8, sizeof(byte_1A76C8));
Read(&byte_1A76C7, sizeof(byte_1A76C7));
Read(&byte_19AE44, sizeof(byte_19AE44));
Read(gStatCount, sizeof(gStatCount));
Read(nextXSprite, sizeof(nextXSprite));
Read(&XWallsUsed, sizeof(XWallsUsed));
Read(&XSectorsUsed, sizeof(XSectorsUsed));
memset(xsprite, 0, sizeof(xsprite));
for (int nSprite = 0; nSprite < kMaxSprites; nSprite++)
{
if (sprite[nSprite].statnum < kMaxStatus)
{
int nXSprite = sprite[nSprite].extra;
if (nXSprite > 0)
{
Read(&xsprite[nXSprite], sizeof(XSPRITE));
UnindexAIState(xsprite[nXSprite].aiState);
}
}
}
memset(xwall, 0, sizeof(xwall));
for (int nWall = 0; nWall < numwalls; nWall++)
{
int nXWall = wall[nWall].extra;
if (nXWall > 0)
Read(&xwall[nXWall], sizeof(XWALL));
}
memset(xsector, 0, sizeof(xsector));
for (int nSector = 0; nSector < numsectors; nSector++)
{
int nXSector = sector[nSector].extra;
if (nXSector > 0)
Read(&xsector[nXSector], sizeof(XSECTOR));
}
Read(xvel, nNumSprites*sizeof(xvel[0]));
Read(yvel, nNumSprites*sizeof(yvel[0]));
Read(zvel, nNumSprites*sizeof(zvel[0]));
Read(&gMapRev, sizeof(gMapRev));
Read(&gSongId, sizeof(gSkyCount));
Read(&gFogMode, sizeof(gFogMode));
arc.Array("sector_filler", qsector_filler, numsectors)
("visibility", gVisibility)
("frameclock", gFrameClock)
("framecount", gFrameCount)
.Array("basewall", baseWall, numwalls)
.SparseArray("basesprite", baseSprite, kMaxSprites, activeSprites)
.Array("basefloor", baseFloor, numsectors)
.Array("baseceil", baseCeil, numsectors)
.Array("velfloor", velFloor, numsectors)
.Array("velceil", velCeil, numsectors)
("hitinfo", gHitInfo)
.Array("statcount", gStatCount, kMaxStatus + 1)
("xwallsused", XWallsUsed)
("xsectorsused", XSectorsUsed)
("fogmode", gFogMode)
#ifdef NOONE_EXTENSIONS
Read(&gModernMap, sizeof(gModernMap));
("modern", gModernMap)
#endif
psky_t *skyInfo = tileSetupSky(DEFAULTPSKY);
Read(skyInfo, sizeof(*skyInfo));
skyInfo->combinedtile = -1;
cheatReset();
Read(&bPlayerCheated, sizeof(bPlayerCheated));
Read(&gNextLevel, sizeof(gNextLevel));
Read(&gGameOptions, sizeof(gGameOptions));
("cheating", bPlayerCheated)
("nextlevel", gNextLevel)
("skyhoriz", pSky->horizfrac)
("skyy", pSky->yoffs)
("scale", pSky->yscale)
.Array("tileofs", pSky->tileofs, countof(pSky->tileofs))
("numtiles", pSky->lognumtiles)
("gameoptions", gGameOptions)
.Array("xwall", xwall, xwallbackup, XWallsUsed) // todo
.Array("xsector", xsector, xsectorbackup, XSectorsUsed)
.SparseArray("xsprite", xsprite, kMaxXSprites, activeXSprites)
.SparseArray("xvel", xvel, kMaxSprites, activeSprites)
.SparseArray("yvel", yvel, kMaxSprites, activeSprites)
.SparseArray("zvel", zvel, kMaxSprites, activeSprites)
.EndObject();
}
void MyLoadSave::Save(void)
{
psky_t *pSky = tileSetupSky(0);
int nNumSprites = 0;
int id = 0x5653424e/*'VSBN'*/;
Write(&id, sizeof(id));
for (int nSprite = 0; nSprite < kMaxSprites; nSprite++)
{
if (sprite[nSprite].statnum < kMaxStatus && nSprite > nNumSprites)
nNumSprites = nSprite;
}
//nNumSprites += 2;
nNumSprites++;
Write(&gGameOptions, sizeof(gGameOptions));
Write(&nNumSprites, sizeof(nNumSprites));
Write(qsector_filler, sizeof(qsector_filler[0])*numsectors);
Write(&pSky->horizfrac, sizeof(pSky->horizfrac));
Write(&pSky->yoffs, sizeof(pSky->yoffs));
Write(&pSky->yscale, sizeof(pSky->yscale));
Write(&gVisibility, sizeof(gVisibility));
Write(pSky->tileofs, sizeof(pSky->tileofs));
Write(&pSky->lognumtiles, sizeof(pSky->lognumtiles));
Write(gotpic, sizeof(gotpic));
Write(gotsector, sizeof(gotsector));
Write(&gFrameClock, sizeof(gFrameClock));
Write(&gFrameCount, sizeof(gFrameCount));
Write(&paused, sizeof(paused));
Write(baseWall, sizeof(baseWall[0])*numwalls);
Write(baseSprite, sizeof(baseSprite[0])*nNumSprites);
Write(baseFloor, sizeof(baseFloor[0])*numsectors);
Write(baseCeil, sizeof(baseCeil[0])*numsectors);
Write(velFloor, sizeof(velFloor[0])*numsectors);
Write(velCeil, sizeof(velCeil[0])*numsectors);
Write(&gHitInfo, sizeof(gHitInfo));
Write(&byte_1A76C6, sizeof(byte_1A76C6));
Write(&byte_1A76C8, sizeof(byte_1A76C8));
Write(&byte_1A76C7, sizeof(byte_1A76C7));
Write(&byte_19AE44, sizeof(byte_19AE44));
Write(gStatCount, sizeof(gStatCount));
Write(nextXSprite, sizeof(nextXSprite));
Write(&XWallsUsed, sizeof(XWallsUsed));
Write(&XSectorsUsed, sizeof(XSectorsUsed));
for (int nSprite = 0; nSprite < kMaxSprites; nSprite++)
{
if (sprite[nSprite].statnum < kMaxStatus)
{
int nXSprite = sprite[nSprite].extra;
if (nXSprite > 0)
{
auto saved = xsprite[nXSprite].aiState;
IndexAIState(xsprite[nXSprite].aiState);
Write(&xsprite[nXSprite], sizeof(XSPRITE));
xsprite[nXSprite].aiState = saved;
}
}
}
for (int nWall = 0; nWall < numwalls; nWall++)
{
int nXWall = wall[nWall].extra;
if (nXWall > 0)
Write(&xwall[nXWall], sizeof(XWALL));
}
for (int nSector = 0; nSector < numsectors; nSector++)
{
int nXSector = sector[nSector].extra;
if (nXSector > 0)
Write(&xsector[nXSector], sizeof(XSECTOR));
}
Write(xvel, nNumSprites*sizeof(xvel[0]));
Write(yvel, nNumSprites*sizeof(yvel[0]));
Write(zvel, nNumSprites*sizeof(zvel[0]));
Write(&gMapRev, sizeof(gMapRev));
Write(&gSongId, sizeof(gSkyCount));
Write(&gFogMode, sizeof(gFogMode));
#ifdef NOONE_EXTENSIONS
Write(&gModernMap, sizeof(gModernMap));
#endif
psky_t *skyInfo = tileSetupSky(DEFAULTPSKY);
Write(skyInfo, sizeof(*skyInfo));
Write(&bPlayerCheated, sizeof(bPlayerCheated));
Write(&gNextLevel, sizeof(gNextLevel));
Write(&gGameOptions, sizeof(gGameOptions));
}
void ViewLoadSaveConstruct(void);
#ifdef NOONE_EXTENSIONS
void NNLoadSaveConstruct(void);
#endif
void LoadSaveSetup(void)
{
new MyLoadSave();
ViewLoadSaveConstruct();
#ifdef NOONE_EXTENSIONS
NNLoadSaveConstruct();
#endif
}
@ -748,6 +643,8 @@ void SerializeActor(FSerializer& arc);
void SerializeAI(FSerializer& arc);
void SerializeGameStats(FSerializer& arc);
void SerializePlayers(FSerializer& arc);
void SerializeView(FSerializer& arc);
void SerializeNNExts(FSerializer& arc);
void GameInterface::SerializeGameState(FSerializer& arc)
{
@ -772,6 +669,8 @@ void GameInterface::SerializeGameState(FSerializer& arc)
}
}
arc.SerializeMemory("activexsprites", activeXSprites.Storage(), activeXSprites.StorageSize());
SerializeState(arc);
InitFreeList(nextXSprite, kMaxXSprites, activeXSprites);
SerializeActor(arc);
SerializeAI(arc);
SerializePlayers(arc);
@ -780,6 +679,27 @@ void GameInterface::SerializeGameState(FSerializer& arc)
SerializeSequences(arc);
SerializeWarp(arc);
SerializeTriggers(arc);
SerializeView(arc);
#ifdef NOONE_EXTENSIONS
SerializeNNExts(arc);
#endif
if (arc.isReading())
{
InitSectorFX();
viewInitializePrediction();
PreloadCache();
if (!gMe->packSlots[1].isActive) // if diving suit is not active, turn off reverb sound effect
sfxSetReverb(0);
ambInit();
for (int i = 0; i < gNetPlayers; i++)
playerSetRace(&gPlayer[i], gPlayer[i].lifeMode);
viewSetErrorMessage("");
Net_ClearFifo();
paused = 0;
Polymost_prepare_loadboard();
Mus_ResumeSaved();
}
}

View file

@ -27,23 +27,5 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
struct FSavegameNode;
BEGIN_BLD_NS
class LoadSave {
public:
static LoadSave head;
static FileWriter *hSFile;
static FileReader hLFile;
static TDeletingArray<LoadSave*> loadSaves;
LoadSave() {
loadSaves.Push(this);
}
virtual ~LoadSave() = default;
virtual void Save(void);
virtual void Load(void);
void Read(void *, int);
void Write(const void *, int);
};
void LoadSaveSetup(void);
extern FixedBitArray<MAXSPRITES> activeXSprites;
END_BLD_NS

View file

@ -31,7 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "eventq.h"
#include "globals.h"
#include "levels.h"
#include "loadsave.h"
#include "messages.h"
#include "player.h"
#include "view.h"

View file

@ -28,7 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "blood.h"
#include "db.h"
#include "gameutil.h"
#include "loadsave.h"
#include "player.h"
#include "view.h"

View file

@ -32,7 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "nnexts.h"
#ifdef NOONE_EXTENSIONS
#include <random>
#include "loadsave.h"
#include "player.h"
#include "aiunicult.h"
#include "triggers.h"
@ -45,6 +44,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "sound.h"
#include "seq.h"
#include "ai.h"
#include "savegamehelp.h"
BEGIN_BLD_NS
@ -5286,43 +5286,83 @@ void callbackGenDudeUpdate(int nSprite) // 24
}
class NNLoadSave : public LoadSave
{
virtual void Load(void);
virtual void Save(void);
};
void NNLoadSave::Load(void)
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
FSerializer& Serialize(FSerializer& arc, const char* keyname, GENDUDEEXTRA& w, GENDUDEEXTRA* def)
{
Read(gSpriteMass, sizeof(gSpriteMass));
Read(&gProxySpritesCount, sizeof(gProxySpritesCount));
Read(gProxySpritesList, sizeof(gProxySpritesList));
Read(&gSightSpritesCount, sizeof(gSightSpritesCount));
Read(gSightSpritesList, sizeof(gSightSpritesList));
Read(&gPhysSpritesCount, sizeof(gPhysSpritesCount));
Read(gPhysSpritesList, sizeof(gPhysSpritesList));
Read(&gImpactSpritesCount, sizeof(gImpactSpritesCount));
Read(gImpactSpritesList, sizeof(gImpactSpritesList));
Read(&gEventRedirectsUsed, sizeof(gEventRedirectsUsed));
if (arc.BeginObject(keyname))
{
arc.Array("initvals", w.initVals, 3)
.Array("availdeaths", w.availDeaths, kDamageMax)
("movespeed", w.moveSpeed)
("firedist", w.fireDist)
("throwdist", w.throwDist)
("curweapon", w.curWeapon)
("weapontype", w.weaponType)
("basedispersion", w.baseDispersion)
("slavecount", w.slaveCount)
("lifeleech", w.nLifeLeech)
.Array("slaves", w.slave, w.slaveCount)
.Array("dmgcontrol", w.dmgControl, kDamageMax)
.Array("updreq", w.updReq, kGenDudePropertyMax)
("flags", w.flags)
.EndObject();
}
return arc;
}
void NNLoadSave::Save(void)
FSerializer& Serialize(FSerializer& arc, const char* keyname, SPRITEMASS& w, SPRITEMASS* def)
{
Write(gSpriteMass, sizeof(gSpriteMass));
Write(&gProxySpritesCount, sizeof(gProxySpritesCount));
Write(gProxySpritesList, sizeof(gProxySpritesList));
Write(&gSightSpritesCount, sizeof(gSightSpritesCount));
Write(gSightSpritesList, sizeof(gSightSpritesList));
Write(&gPhysSpritesCount, sizeof(gPhysSpritesCount));
Write(gPhysSpritesList, sizeof(gPhysSpritesList));
Write(&gImpactSpritesCount, sizeof(gImpactSpritesCount));
Write(gImpactSpritesList, sizeof(gImpactSpritesList));
Write(&gEventRedirectsUsed, sizeof(gEventRedirectsUsed));
static SPRITEMASS nul;
if (arc.isReading()) w = {};
if (arc.BeginObject(keyname))
{
arc ("seq", w.seqId, &nul.seqId)
("picnum", w.picnum, &nul.picnum)
("xrepeat", w.xrepeat, &nul.xrepeat)
("yrepeat", w.yrepeat, &nul.yrepeat)
("clipdist", w.clipdist)
("mass", w.mass)
("airvel", w.airVel)
("fraction", w.fraction)
.EndObject();
}
return arc;
}
void NNLoadSaveConstruct(void)
void SerializeNNExts(FSerializer& arc)
{
new NNLoadSave();
if (arc.BeginObject("nnexts"))
{
// the GenDudeArray only contains valid info for kDudeModernCustom and kDudeModernCustomBurning so only save the relevant entries as these are not small.
bool foundsome = false;
for (int i = 0; i < kMaxSprites; i++)
{
if (activeSprites[i] && (sprite[i].type == kDudeModernCustom || sprite[i].type == kDudeModernCustomBurning))
{
if (!foundsome) arc.BeginArray("gendudeextra");
foundsome = true;
arc(nullptr, gGenDudeExtra[i]);
}
}
if (foundsome) arc.EndArray();
arc.SparseArray("spritemass", gSpriteMass, kMaxSprites, activeXSprites)
("proxyspritescount", gProxySpritesCount)
.Array("proxyspriteslist", gProxySpritesList, gProxySpritesCount)
("sightspritescount", gSightSpritesCount)
.Array("sightspriteslist", gSightSpritesList, gSightSpritesCount)
("physspritescount", gPhysSpritesCount)
.Array("physspriteslist", gPhysSpritesList, gPhysSpritesCount)
("impactspritescount", gImpactSpritesCount)
.Array("impactspriteslist", gImpactSpritesList, gImpactSpritesCount)
("eventredirects", gEventRedirectsUsed)
.EndObject();
}
}
///////////////////////////////////////////////////////////////////

View file

@ -36,7 +36,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gib.h"
#include "globals.h"
#include "levels.h"
#include "loadsave.h"
#include "player.h"
#include "seq.h"
#include "sound.h"

View file

@ -33,7 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "endgame.h"
#include "aistate.h"
#include "loadsave.h"
#include "sectorfx.h"
#include "choke.h"
#include "view.h"

View file

@ -33,7 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "endgame.h"
#include "aistate.h"
#include "loadsave.h"
#include "sectorfx.h"
#include "choke.h"
#include "view.h"

View file

@ -34,7 +34,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "eventq.h"
#include "globals.h"
#include "levels.h"
#include "loadsave.h"
#include "sound.h"
#include "seq.h"
#include "gameutil.h"

View file

@ -41,7 +41,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gib.h"
#include "globals.h"
#include "levels.h"
#include "loadsave.h"
#include "player.h"
#include "seq.h"
#include "qav.h"

View file

@ -33,7 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "endgame.h"
#include "aistate.h"
#include "loadsave.h"
#include "sectorfx.h"
#include "choke.h"
#include "view.h"
@ -481,8 +480,8 @@ void UpdateBlend()
videoTintBlood(nRed, nGreen, nBlue);
}
char otherMirrorGotpic[2];
char bakMirrorGotpic[2];
uint8_t otherMirrorGotpic[2];
uint8_t bakMirrorGotpic[2];
// int gVisibility;
int deliriumTilt, deliriumTurn, deliriumPitch;
@ -988,7 +987,7 @@ void viewDrawScreen(bool sceneonly)
gChoke.animateChoke(160, zn, (int)gInterpolate);
}
#if 0
if (byte_1A76C6)
if (drawtile_2048)
{
DrawStatSprite(2048, xdim-15, 20);
}
@ -1065,36 +1064,17 @@ bool GameInterface::DrawAutomapPlayer(int x, int y, int z, int a)
return true;
}
class ViewLoadSave : public LoadSave {
public:
void Load(void);
void Save(void);
};
void ViewLoadSave::Load(void)
void SerializeView(FSerializer& arc)
{
Read(otherMirrorGotpic, sizeof(otherMirrorGotpic));
Read(bakMirrorGotpic, sizeof(bakMirrorGotpic));
Read(&gScreenTilt, sizeof(gScreenTilt));
Read(&deliriumTilt, sizeof(deliriumTilt));
Read(&deliriumTurn, sizeof(deliriumTurn));
Read(&deliriumPitch, sizeof(deliriumPitch));
if (arc.BeginObject("view"))
{
arc("screentilt", gScreenTilt)
("deliriumtilt", deliriumTilt)
("deliriumturn", deliriumTurn)
("deliriumpitch", deliriumPitch)
.EndObject();
}
}
void ViewLoadSave::Save(void)
{
Write(otherMirrorGotpic, sizeof(otherMirrorGotpic));
Write(bakMirrorGotpic, sizeof(bakMirrorGotpic));
Write(&gScreenTilt, sizeof(gScreenTilt));
Write(&deliriumTilt, sizeof(deliriumTilt));
Write(&deliriumTurn, sizeof(deliriumTurn));
Write(&deliriumPitch, sizeof(deliriumPitch));
}
void ViewLoadSaveConstruct(void)
{
new ViewLoadSave();
}
END_BLD_NS

View file

@ -29,7 +29,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "db.h"
#include "gameutil.h"
#include "levels.h"
#include "loadsave.h"
#include "view.h"
#include "nnexts.h"
@ -333,33 +332,4 @@ void SerializeWarp(FSerializer& arc)
}
}
class WarpLoadSave : public LoadSave
{
public:
virtual void Load();
virtual void Save();
};
void WarpLoadSave::Load()
{
Read(gStartZone, sizeof(gStartZone));
Read(gUpperLink, sizeof(gUpperLink));
Read(gLowerLink, sizeof(gLowerLink));
}
void WarpLoadSave::Save()
{
Write(gStartZone, sizeof(gStartZone));
Write(gUpperLink, sizeof(gUpperLink));
Write(gLowerLink, sizeof(gLowerLink));
}
void WarpLoadSaveConstruct(void)
{
new WarpLoadSave();
}
END_BLD_NS

View file

@ -38,7 +38,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gameutil.h"
#include "globals.h"
#include "levels.h"
#include "loadsave.h"
#include "player.h"
#include "qav.h"
#include "seq.h"

View file

@ -307,7 +307,6 @@ typedef struct {
int16_t tileofs[MAXPSKYTILES]; // for 0 <= j < (1<<lognumtiles): tile offset relative to basetile
int32_t yscale;
int combinedtile;
} psky_t;
// Index of map-global (legacy) multi-sky:

View file

@ -243,6 +243,18 @@ void bfirst_search_try(T *const list, uint8_t *const bitmap, T *const eltnumptr,
/* End dependence on compat.o object. */
inline FSerializer& Serialize(FSerializer& arc, const char* key, vec2_t& c, vec2_t* def)
{
if (def && !memcmp(&c, def, sizeof(c))) return arc;
if (arc.BeginObject(key))
{
arc("x", c.x, def? &def->x : nullptr)
("y", c.y, def ? &def->y : nullptr)
.EndObject();
}
return arc;
}
inline FSerializer& Serialize(FSerializer& arc, const char* key, vec3_t& c, vec3_t* def)
{
if (def && !memcmp(&c, def, sizeof(c))) return arc;
@ -256,5 +268,4 @@ inline FSerializer& Serialize(FSerializer& arc, const char* key, vec3_t& c, vec3
return arc;
}
#endif // compat_h_

View file

@ -808,14 +808,12 @@ psky_t * tileSetupSky(int32_t const tilenum)
for (auto& sky : multipskies)
if (tilenum == sky.tilenum)
{
sky.combinedtile = -1; // invalidate the old content
return &sky;
}
multipskies.Reserve(1);
multipskies.Last() = {};
multipskies.Last().tilenum = tilenum;
multipskies.Last().combinedtile = -1;
multipskies.Last().yscale = 65536;
return &multipskies.Last();
}