- removed the old actor savegame code and instead implemented a virtual Serialize function.

This isn't hooked up yet, currently savegames are non-functional. They will come back once the global actor arrays are no longer relevant for maintenance.
This commit is contained in:
Christoph Oelckers 2021-12-05 09:20:41 +01:00
parent e79cd8d87f
commit 4cecb6f955
11 changed files with 101 additions and 127 deletions

View file

@ -17,6 +17,9 @@ public:
DCoreActor* prevStat, * nextStat; DCoreActor* prevStat, * nextStat;
DCoreActor* prevSect, * nextSect; DCoreActor* prevSect, * nextSect;
virtual ~DCoreActor() = default;
virtual void Serialize(FSerializer& arc);
bool exists() const bool exists() const
{ {
return (unsigned)s().statnum < MAXSTATUS; return (unsigned)s().statnum < MAXSTATUS;
@ -322,10 +325,6 @@ public:
using CoreSectIterator = TSectIterator<DCoreActor>; using CoreSectIterator = TSectIterator<DCoreActor>;
// Only to be used by initial actor spawns!
void InsertActorSect(DCoreActor* actor, sectortype* sector, bool tail = false);
void InsertActorStat(DCoreActor* actor, int stat, bool tail = false);
DCoreActor* InsertActor(sectortype* sector, int stat, bool forcetail = false); DCoreActor* InsertActor(sectortype* sector, int stat, bool forcetail = false);
int DeleteActor(DCoreActor* actor); int DeleteActor(DCoreActor* actor);
void ChangeActorSect(DCoreActor* actor, sectortype* sector, bool forcetail = false); void ChangeActorSect(DCoreActor* actor, sectortype* sector, bool forcetail = false);

View file

@ -75,7 +75,6 @@ extern FString BackupSaveGame;
int SaveVersion; int SaveVersion;
void SerializeMap(FSerializer &arc); void SerializeMap(FSerializer &arc);
FixedBitArray<MAXSPRITES> activeSprites;
CVAR(String, cl_savedir, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(String, cl_savedir, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -653,33 +652,17 @@ FSerializer &Serialize(FSerializer &arc, const char *key, walltype &c, walltype
} }
void DCoreActor::Serialize(FSerializer& arc)
{
// nothing here yet.
}
void SerializeMap(FSerializer& arc) void SerializeMap(FSerializer& arc)
{ {
// create a map of all used sprites so that we can use that elsewhere to only save what's needed.
activeSprites.Zero();
if (arc.isWriting())
{
for (int i=0; i<MAXSPRITES;i++)
{
if (sprite[i].statnum != MAXSTATUS)
{
activeSprites.Set(i);
}
}
}
else
{
memset(sprite, 0, sizeof(sprite[0]) * MAXSPRITES);
InitSpriteLists();
zsp = sprite[0];
}
if (arc.BeginObject("engine")) if (arc.BeginObject("engine"))
{ {
arc.SerializeMemory("activesprites", activeSprites.Storage(), activeSprites.StorageSize()) arc("numsectors", numsectors)
.SparseArray("sprites", sprite, MAXSPRITES, activeSprites)
.SparseArray("spriteext", spriteext, MAXSPRITES, activeSprites)
("numsectors", numsectors)
("sectors", sector, sectorbackup) ("sectors", sector, sectorbackup)
("numwalls", numwalls) ("numwalls", numwalls)
("walls", wall, wallbackup) ("walls", wall, wallbackup)

View file

@ -5,8 +5,6 @@
#include "gamefuncs.h" #include "gamefuncs.h"
#include "coreactor.h" #include "coreactor.h"
extern FixedBitArray<MAXSPRITES> activeSprites;
// Savegame utilities // Savegame utilities
class FileReader; class FileReader;
extern int SaveVersion; extern int SaveVersion;

View file

@ -13,6 +13,7 @@ struct SPRITEHIT
class DBloodActor : public DCoreActor class DBloodActor : public DCoreActor
{ {
using Super = DCoreActor;
DBloodActor* base(); DBloodActor* base();
public: public:
@ -39,6 +40,8 @@ public:
index = (int(this - base())); index = (int(this - base()));
} }
void Serialize(FSerializer& arc) override;
DBloodActor& operator=(const DBloodActor& other) = default; DBloodActor& operator=(const DBloodActor& other) = default;
void Clear() void Clear()

View file

@ -464,52 +464,41 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor*& w, D
return arc; return arc;
} }
FSerializer& Serialize(FSerializer& arc, const char* keyname, DBloodActor& w, DBloodActor* def) void DBloodActor::Serialize(FSerializer& arc)
{ {
static DBloodActor nul; Super::Serialize(arc);
if (!def) arc("xvel", xvel)
{ ("yvel", yvel)
def = &nul; ("zvel", zvel)
if (arc.isReading()) w.Clear(); ("hasx", hasx);
}
if (arc.BeginObject(keyname))
{
arc("xvel", w.xvel, def->xvel)
("yvel", w.yvel, def->yvel)
("zvel", w.zvel, def->zvel)
("hasx", w.hasx, def->hasx);
// The rest is only relevant if the actor has an xsprite. // The rest is only relevant if the actor has an xsprite.
if (w.hasX()) if (hasX())
{ {
arc("xsprite", w.xsprite, def->xsprite) arc("xsprite", xsprite)
("dudeslope", w.dudeSlope, def->dudeSlope) ("dudeslope", dudeSlope)
("dudeextra", w.dudeExtra, def->dudeExtra) ("dudeextra", dudeExtra)
("explosionflag", w.explosionhackflag, def->explosionhackflag) ("explosionflag", explosionhackflag)
("spritehit", w.hit, def->hit) ("spritehit", hit)
("basepoint", w.basePoint, def->basePoint) ("basepoint", basePoint)
("owneractor", w.ownerActor, def->ownerActor); ("owneractor", ownerActor);
#ifdef NOONE_EXTENSIONS #ifdef NOONE_EXTENSIONS
if (gModernMap) if (gModernMap)
{ {
arc("spritemass", w.spriteMass, def->spriteMass) // no treatment for old savegames. If this gets lost it is not critical arc("spritemass", spriteMass)
("prevmarker", w.prevmarker, def->prevmarker) ("prevmarker", prevmarker)
.Array("conditions", w.condition, def->condition, 2); .Array("conditions", condition, 2);
// GenDudeExtra only contains valid info for kDudeModernCustom and kDudeModernCustomBurning so only save when needed as these are not small. // GenDudeExtra only contains valid info for kDudeModernCustom and kDudeModernCustomBurning so only save when needed as these are not small.
if (w.s().type == kDudeModernCustom || w.s().type == kDudeModernCustomBurning) if (s().type == kDudeModernCustom || s().type == kDudeModernCustomBurning)
{ {
arc("gendudeextra", w.genDudeExtra); arc("gendudeextra", genDudeExtra);
} }
} }
#endif #endif
} }
arc.EndObject();
}
return arc;
} }
FSerializer& Serialize(FSerializer& arc, const char* keyname, XWALL& w, XWALL* def) FSerializer& Serialize(FSerializer& arc, const char* keyname, XWALL& w, XWALL* def)
@ -692,9 +681,7 @@ void SerializeState(FSerializer& arc)
("scale", pSky->yscale) ("scale", pSky->yscale)
.Array("tileofs", pSky->tileofs, countof(pSky->tileofs)) .Array("tileofs", pSky->tileofs, countof(pSky->tileofs))
("numtiles", pSky->lognumtiles) ("numtiles", pSky->lognumtiles)
("gameoptions", gGameOptions) ("gameoptions", gGameOptions);
.SparseArray("actors", bloodActors, kMaxSprites, activeSprites);
arc.EndObject(); arc.EndObject();
} }

View file

@ -283,39 +283,38 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
} }
FSerializer& Serialize(FSerializer& arc, const char* keyname, DDukeActor& w, DDukeActor* def) void DDukeActor::Serialize(FSerializer& arc)
{ {
if (!def) def = &hittype[MAXSPRITES]; //AActor* def = GetDefault();
if (arc.BeginObject(keyname))
{ Super::Serialize(arc);
arc("cgg", w.cgg, def->cgg)
("spriteextra", w.spriteextra, def->spriteextra) arc("cgg", cgg)
("picnum", w.picnum, def->picnum) ("spriteextra", spriteextra)
("ang", w.ang, def->ang) ("picnum", picnum)
("extra", w.extra, def->extra) ("ang", ang)
("owneractor", w.ownerActor, def->ownerActor) ("extra", extra)
("owner", w.hitOwnerActor, def->hitOwnerActor) ("owneractor", ownerActor)
("movflag", w.movflag, def->movflag) ("owner", hitOwnerActor)
("tempang", w.tempang, def->tempang) ("movflag", movflag)
("actorstayput", w.actorstayput, def->actorstayput) ("tempang", tempang)
("dispicnum", w.dispicnum, def->dispicnum) ("actorstayput", actorstayput)
("timetosleep", w.timetosleep, def->timetosleep) ("dispicnum", dispicnum)
("floorz", w.floorz, def->floorz) ("timetosleep", timetosleep)
("ceilingz", w.ceilingz, def->ceilingz) ("floorz", floorz)
("lastvx", w.lastvx, def->lastvx) ("ceilingz", ceilingz)
("lastvy", w.lastvy, def->lastvy) ("lastvx", lastvx)
("aflags", w.aflags, def->aflags) ("lastvy", lastvy)
("saved_ammo", w.saved_ammo, def->saved_ammo) ("aflags", aflags)
("temp_actor", w.temp_actor, def->temp_actor) ("saved_ammo", saved_ammo)
("seek_actor", w.seek_actor, def->seek_actor) ("temp_actor", temp_actor)
.Array("temp_data", w.temp_data, def->temp_data, 6) ("seek_actor", seek_actor)
.Array("temo_wall", w.temp_walls, def->temp_walls,2) .Array("temp_data", temp_data, 6)
("temp_sect", w.temp_sect, def->temp_sect) .Array("temo_wall", temp_walls, 2)
.EndObject(); ("temp_sect", temp_sect);
}
return arc;
} }
FSerializer& Serialize(FSerializer& arc, const char* keyname, Cycler& w, Cycler* def) FSerializer& Serialize(FSerializer& arc, const char* keyname, Cycler& w, Cycler* def)
{ {
static Cycler nul; static Cycler nul;
@ -348,8 +347,7 @@ void GameInterface::SerializeGameState(FSerializer& arc)
{ {
arc("multimode", ud.multimode); arc("multimode", ud.multimode);
arc.SparseArray("actors", hittype, MAXSPRITES, activeSprites) arc("skill", ud.player_skill)
("skill", ud.player_skill)
("from_bonus", ud.from_bonus) ("from_bonus", ud.from_bonus)
("secretlevel", ud.secretlevel) ("secretlevel", ud.secretlevel)
("respawn_monsters", ud.respawn_monsters) ("respawn_monsters", ud.respawn_monsters)

View file

@ -23,6 +23,8 @@ struct STATUSBARTYPE
struct DDukeActor : public DCoreActor struct DDukeActor : public DCoreActor
{ {
using Super = DCoreActor;
uint8_t cgg; uint8_t cgg;
uint8_t spriteextra; // moved here for easier maintenance. This was originally a hacked in field in the sprite structure called 'filler'. uint8_t spriteextra; // moved here for easier maintenance. This was originally a hacked in field in the sprite structure called 'filler'.
DDukeActor* ownerActor, * hitOwnerActor; DDukeActor* ownerActor, * hitOwnerActor;
@ -99,6 +101,9 @@ struct DDukeActor : public DCoreActor
// only valid for real players - just here to abstract yvel. // only valid for real players - just here to abstract yvel.
return s->yvel; return s->yvel;
} }
void Serialize(FSerializer& arc) override;
}; };
extern DDukeActor hittype[MAXSPRITES + 1]; extern DDukeActor hittype[MAXSPRITES + 1];
inline DDukeActor* DDukeActor::array() { return hittype; } inline DDukeActor* DDukeActor::array() { return hittype; }

View file

@ -570,28 +570,24 @@ bool GameInterface::CanSave()
return new GameInterface; return new GameInterface;
} }
FSerializer& Serialize(FSerializer& arc, const char* keyname, DExhumedActor& w, DExhumedActor* def) void DExhumedActor::Serialize(FSerializer& arc)
{ {
if (arc.BeginObject(keyname)) Super::Serialize(arc);
{ arc("phase", nPhase)
arc("phase", w.nPhase) ("health", nHealth)
("health", w.nHealth) ("frame", nFrame)
("frame", w.nFrame) ("action", nAction)
("action", w.nAction) ("target", pTarget)
("target", w.pTarget) ("count", nCount)
("count", w.nCount) ("run", nRun)
("run", w.nRun) ("index", nIndex)
("index", w.nIndex) ("index2", nIndex2)
("index2", w.nIndex2) ("channel", nChannel)
("channel", w.nChannel) ("damage", nDamage)
("damage", w.nDamage)
("turn", w.nTurn) ("turn", nTurn)
("x", w.x) ("x", x)
("y", w.y) ("y", y);
.EndObject();
}
return arc;
} }
void SerializeState(FSerializer& arc) void SerializeState(FSerializer& arc)
@ -622,7 +618,6 @@ void SerializeState(FSerializer& arc)
("slipmode", bSlipMode) ("slipmode", bSlipMode)
("PlayClock", PlayClock) ("PlayClock", PlayClock)
("spiritsprite", pSpiritSprite) ("spiritsprite", pSpiritSprite)
.SparseArray("actors", exhumedActors, kMaxSprites, activeSprites)
.EndObject(); .EndObject();
} }
} }

View file

@ -16,6 +16,8 @@ enum
class DExhumedActor : public DCoreActor class DExhumedActor : public DCoreActor
{ {
using Super = DCoreActor;
DExhumedActor* base(); DExhumedActor* base();
public: public:
@ -48,6 +50,9 @@ public:
void Clear() void Clear()
{ {
} }
void Serialize(FSerializer& arc) override;
}; };
extern DExhumedActor exhumedActors[MAXSPRITES]; extern DExhumedActor exhumedActors[MAXSPRITES];

View file

@ -1109,19 +1109,16 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, TRACK& w, TRACK* d
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
FSerializer& Serialize(FSerializer& arc, const char* keyname, DSWActor& w, DSWActor* def) void DSWActor::Serialize(FSerializer& arc)
{ {
Super::Serialize(arc);
if (arc.isReading()) if (arc.isReading())
{ {
w.Clear(); // nuke the User before loading anything.
Clear();
} }
if (arc.BeginObject(keyname)) arc("hasuser", hasUser);
{ if (hasUser) arc("user", user); // only write if defined.
arc("hasuser", w.hasUser);
if (w.hasUser) arc("user", w.user); // only write if defined.
arc.EndObject();
}
return arc;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1139,8 +1136,7 @@ void GameInterface::SerializeGameState(FSerializer& arc)
{ {
preSerializePanelSprites(arc); preSerializePanelSprites(arc);
so_serializeinterpolations(arc); so_serializeinterpolations(arc);
arc .SparseArray("actors", swActors, MAXSPRITES, activeSprites) arc ("numplayers", numplayers)
("numplayers", numplayers)
.Array("players", Player, numplayers) .Array("players", Player, numplayers)
("skill", Skill) ("skill", Skill)
("screenpeek", screenpeek) ("screenpeek", screenpeek)

View file

@ -7,6 +7,8 @@ BEGIN_SW_NS
class DSWActor : public DCoreActor class DSWActor : public DCoreActor
{ {
using Super = DCoreActor;
DSWActor* base(); DSWActor* base();
public: public:
@ -40,6 +42,9 @@ public:
hasUser = false; hasUser = false;
user.Clear(); user.Clear();
} }
void Serialize(FSerializer& arc) override;
}; };
extern DSWActor swActors[MAXSPRITES]; extern DSWActor swActors[MAXSPRITES];