# Conflicts:
#	src/CMakeLists.txt
#	src/g_level.cpp
#	src/p_saveg.cpp
#	src/r_defs.h
#	src/version.h

(note that this commit will not compile!)
This commit is contained in:
Christoph Oelckers 2016-09-24 00:40:15 +02:00
commit 6bfbe30b99
201 changed files with 21931 additions and 6730 deletions

View file

@ -1178,7 +1178,6 @@ set (PCH_SOURCES
dthinker.cpp
edata.cpp
f_wipe.cpp
farchive.cpp
files.cpp
g_doomedmap.cpp
g_game.cpp
@ -1257,8 +1256,9 @@ set (PCH_SOURCES
p_xlat.cpp
parsecontext.cpp
po_man.cpp
portal.cpp
portal.cpp
r_utility.cpp
serializer.cpp
sc_man.cpp
st_stuff.cpp
statistics.cpp
@ -1360,7 +1360,6 @@ set (PCH_SOURCES
thingdef/thingdef_properties.cpp
thingdef/thingdef_states.cpp
xlat/parse_xlat.cpp
fragglescript/t_fspic.cpp
fragglescript/t_func.cpp
fragglescript/t_load.cpp
fragglescript/t_oper.cpp
@ -1564,6 +1563,7 @@ source_group("Games\\Strife Game" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DI
source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+")
source_group("Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/math/.+")
source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+")
source_group("RapidJSON" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/.+")
source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+")
source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+")
source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+")

View file

@ -583,8 +583,9 @@ public:
void Destroy ();
~AActor ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void PostSerialize();
static AActor *StaticSpawn (PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);
inline AActor *GetDefault () const
@ -988,7 +989,7 @@ public:
double Speed;
double FloatSpeed;
WORD sprite; // used to find patch_t and flip value
int sprite; // used to find patch_t and flip value
BYTE frame; // sprite frame to draw
DVector2 Scale; // Scaling values; 1 is normal size
FRenderStyle RenderStyle; // Style to draw this actor with
@ -1183,8 +1184,9 @@ public:
private:
static AActor *TIDHash[128];
static inline int TIDHASH (int key) { return key & 127; }
public:
static FSharedStringArena mStringPropertyData;
private:
friend class FActorIterator;
friend bool P_IsTIDUsed(int tid);

View file

@ -38,7 +38,7 @@
#include "gi.h"
#include "p_setup.h"
#include "c_bind.h"
#include "farchive.h"
#include "serializer.h"
#include "r_renderer.h"
#include "r_sky.h"
#include "sbar.h"
@ -3106,13 +3106,14 @@ void AM_Drawer ()
//
//=============================================================================
void AM_SerializeMarkers(FArchive &arc)
void AM_SerializeMarkers(FSerializer &arc)
{
arc << markpointnum;
for (int i=0; i<AM_NUMMARKPOINTS; i++)
if (arc.BeginObject("automarkers"))
{
arc << markpoints[i].x << markpoints[i].y;
arc("markpointnum", markpointnum)
.Array("markpoints", &markpoints[0].x, AM_NUMMARKPOINTS*2) // write as a double array.
("scale_mtof", scale_mtof)
("scale_ftom", scale_ftom)
.EndObject();
}
arc << scale_mtof;
arc << scale_ftom;
}

View file

@ -23,7 +23,7 @@
#define __AMMAP_H__
struct event_t;
class FArchive;
class FSerializer;
void AM_StaticInit();
@ -45,7 +45,7 @@ void AM_Stop (void);
void AM_NewResolution ();
void AM_ToggleMap ();
void AM_LevelInit ();
void AM_SerializeMarkers(FArchive &arc);
void AM_SerializeMarkers(FSerializer &arc);
#endif

View file

@ -12,7 +12,7 @@
#include "cmdlib.h"
#include "teaminfo.h"
#include "d_net.h"
#include "farchive.h"
#include "serializer.h"
#include "d_player.h"
IMPLEMENT_POINTY_CLASS(DBot)
@ -55,31 +55,44 @@ void DBot::Clear ()
old = { 0, 0 };
}
void DBot::Serialize (FArchive &arc)
FSerializer &Serialize(FSerializer &arc, const char *key, botskill_t &skill, botskill_t *def)
{
if (arc.BeginObject(key))
{
arc("aiming", skill.aiming)
("perfection", skill.perfection)
("reaction", skill.reaction)
("isp", skill.isp)
.EndObject();
}
return arc;
}
void DBot::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << player
<< Angle
<< dest
<< prev
<< enemy
<< missile
<< mate
<< last_mate
<< skill
<< t_active
<< t_respawn
<< t_strafe
<< t_react
<< t_fight
<< t_roam
<< t_rocket
<< first_shot
<< sleft
<< allround
<< increase
<< old;
arc("player", player)
("angle", Angle)
("dest", dest)
("prev", prev)
("enemy", enemy)
("missile", missile)
("mate", mate)
("lastmate", last_mate)
("skill", skill)
("active", t_active)
("respawn", t_respawn)
("strafe", t_strafe)
("react", t_react)
("fight", t_fight)
("roam", t_roam)
("rocket", t_rocket)
("firstshot", first_shot)
("sleft", sleft)
("allround", allround)
("increase", increase)
("old", old);
}
void DBot::Tick ()
@ -193,11 +206,6 @@ CCMD (listbots)
Printf ("> %d bots\n", count);
}
FArchive &operator<< (FArchive &arc, botskill_t &skill)
{
return arc << skill.aiming << skill.perfection << skill.reaction << skill.isp;
}
// set the bot specific weapon information
// This is intentionally not in the weapon definition anymore.
void InitBotStuff()

View file

@ -58,8 +58,6 @@ struct botskill_t
int isp; //Instincts of Self Preservation. Personality
};
FArchive &operator<< (FArchive &arc, botskill_t &skill);
enum
{
BOTINUSE_No,
@ -142,7 +140,7 @@ public:
DBot ();
void Clear ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
//(b_think.cpp)

View file

@ -811,7 +811,7 @@ CCMD (load)
return;
}
FString fname = argv[1];
DefaultExtension (fname, ".zds");
DefaultExtension (fname, "." SAVEGAME_EXT);
G_LoadGame (fname);
}
@ -831,7 +831,7 @@ CCMD (save)
return;
}
FString fname = argv[1];
DefaultExtension (fname, ".zds");
DefaultExtension (fname, "." SAVEGAME_EXT);
G_SaveGame (fname, argv.argc() > 2 ? argv[2] : argv[1]);
}

View file

@ -53,7 +53,7 @@
#include "v_text.h"
#include "d_net.h"
#include "d_main.h"
#include "farchive.h"
#include "serializer.h"
// MACROS ------------------------------------------------------------------
@ -65,7 +65,7 @@ class DWaitingCommand : public DThinker
public:
DWaitingCommand (const char *cmd, int tics);
~DWaitingCommand ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
private:
@ -189,10 +189,11 @@ static const char *KeyConfCommands[] =
IMPLEMENT_CLASS (DWaitingCommand)
void DWaitingCommand::Serialize (FArchive &arc)
void DWaitingCommand::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << Command << TicsLeft;
arc("command", Command)
("ticsleft", TicsLeft);
}
DWaitingCommand::DWaitingCommand ()

View file

@ -69,7 +69,7 @@
#include "i_system.h"
#include "doomerrors.h"
#include "p_effect.h"
#include "farchive.h"
#include "serializer.h"
#include "vmbuilder.h"
// [SO] Just the way Randy said to do it :)
@ -3198,8 +3198,8 @@ PClassActor *ADehackedPickup::DetermineType ()
return NULL;
}
void ADehackedPickup::Serialize(FArchive &arc)
void ADehackedPickup::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc << droppedbymonster;
arc("droppedbymonster", droppedbymonster);
}

View file

@ -48,7 +48,8 @@ public:
bool TryPickup (AActor *&toucher);
void PlayPickupSound (AActor *toucher);
void DoPickupSpecial (AActor *toucher);
void Serialize(FArchive &arc);
void Serialize(FSerializer &arc);
private:
PClassActor *DetermineType ();
AInventory *RealPickup;

View file

@ -2580,7 +2580,7 @@ void D_DoomMain (void)
{
FString file(v);
FixPathSeperator (file);
DefaultExtension (file, ".zds");
DefaultExtension (file, "." SAVEGAME_EXT);
G_LoadGame (file);
}

View file

@ -56,7 +56,7 @@
#include "r_data/r_translate.h"
#include "templates.h"
#include "cmdlib.h"
#include "farchive.h"
#include "serializer.h"
static FRandom pr_pickteam ("PickRandomTeam");
@ -880,69 +880,75 @@ void D_ReadUserInfoStrings (int pnum, BYTE **stream, bool update)
*stream += strlen (*((char **)stream)) + 1;
}
void WriteUserInfo(FArchive &arc, userinfo_t &info)
void WriteUserInfo(FSerializer &arc, userinfo_t &info)
{
TMapIterator<FName, FBaseCVar *> it(info);
TMap<FName, FBaseCVar *>::Pair *pair;
FName name;
UCVarValue val;
int i;
while (it.NextPair(pair))
if (arc.BeginObject("userinfo"))
{
name = pair->Key;
arc << name;
switch (name.GetIndex())
TMapIterator<FName, FBaseCVar *> it(info);
TMap<FName, FBaseCVar *>::Pair *pair;
FString name;
const char *string;
UCVarValue val;
int i;
while (it.NextPair(pair))
{
case NAME_Skin:
arc.WriteString(skins[info.GetSkin()].name);
break;
name = pair->Key;
name.ToLower();
switch (pair->Key.GetIndex())
{
case NAME_Skin:
string = skins[info.GetSkin()].name;
break;
case NAME_PlayerClass:
i = info.GetPlayerClassNum();
arc.WriteString(i == -1 ? "Random" : PlayerClasses[i].Type->DisplayName.GetChars());
break;
case NAME_PlayerClass:
i = info.GetPlayerClassNum();
string = (i == -1 ? "Random" : PlayerClasses[i].Type->DisplayName.GetChars());
break;
default:
val = pair->Value->GetGenericRep(CVAR_String);
arc.WriteString(val.String);
break;
default:
val = pair->Value->GetGenericRep(CVAR_String);
string = val.String;
break;
}
arc.StringPtr(name, string);
}
arc.EndObject();
}
name = NAME_None;
arc << name;
}
void ReadUserInfo(FArchive &arc, userinfo_t &info, FString &skin)
void ReadUserInfo(FSerializer &arc, userinfo_t &info, FString &skin)
{
FName name;
FBaseCVar **cvar;
char *str = NULL;
UCVarValue val;
const char *key;
const char *str;
info.Reset();
skin = NULL;
for (arc << name; name != NAME_None; arc << name)
if (arc.BeginObject("userinfo"))
{
cvar = info.CheckKey(name);
arc << str;
if (cvar != NULL && *cvar != NULL)
while ((key = arc.GetKey()))
{
switch (name)
arc.StringPtr(nullptr, str);
name = key;
cvar = info.CheckKey(name);
if (cvar != NULL && *cvar != NULL)
{
case NAME_Team: info.TeamChanged(atoi(str)); break;
case NAME_Skin: skin = str; break; // Caller must call SkinChanged() once current calss is known
case NAME_PlayerClass: info.PlayerClassChanged(str); break;
default:
val.String = str;
(*cvar)->SetGenericRep(val, CVAR_String);
break;
switch (name)
{
case NAME_Team: info.TeamChanged(atoi(str)); break;
case NAME_Skin: skin = str; break; // Caller must call SkinChanged() once current calss is known
case NAME_PlayerClass: info.PlayerClassChanged(str); break;
default:
val.String = str;
(*cvar)->SetGenericRep(val, CVAR_String);
break;
}
}
}
}
if (str != NULL)
{
delete[] str;
arc.EndObject();
}
}

View file

@ -102,7 +102,8 @@ class APlayerPawn : public AActor
DECLARE_CLASS_WITH_META(APlayerPawn, AActor, PClassPlayerPawn)
HAS_OBJECT_POINTERS
public:
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual void PostBeginPlay();
virtual void Tick();
@ -374,8 +375,8 @@ struct userinfo_t : TMap<FName,FBaseCVar *>
int ColorSetChanged(int setnum);
};
void ReadUserInfo(FArchive &arc, userinfo_t &info, FString &skin);
void WriteUserInfo(FArchive &arc, userinfo_t &info);
void ReadUserInfo(FSerializer &arc, userinfo_t &info, FString &skin);
void WriteUserInfo(FSerializer &arc, userinfo_t &info);
//
// Extended player object info: player_t
@ -387,7 +388,7 @@ public:
~player_t();
player_t &operator= (const player_t &p);
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
size_t FixPointers (const DObject *obj, DObject *replacement);
size_t PropagateMark();
@ -545,8 +546,6 @@ public:
// Bookkeeping on players - state.
extern player_t players[MAXPLAYERS];
FArchive &operator<< (FArchive &arc, player_t *&p);
void P_CheckPlayerSprite(AActor *mo, int &spritenum, DVector2 &scale);
inline void AActor::SetFriendPlayer(player_t *player)

View file

@ -38,7 +38,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "cmdlib.h"
#include "farchive.h"
#include "serializer.h"
char *ReadString (BYTE **stream)
@ -287,27 +287,33 @@ int PackUserCmd (const usercmd_t *ucmd, const usercmd_t *basis, BYTE **stream)
return int(*stream - start);
}
FArchive &operator<< (FArchive &arc, ticcmd_t &cmd)
FSerializer &Serialize(FSerializer &arc, const char *key, ticcmd_t &cmd, ticcmd_t *def)
{
return arc << cmd.consistancy << cmd.ucmd;
if (arc.BeginObject(key))
{
arc("consistency", cmd.consistancy)
("ucmd", cmd.ucmd)
.EndObject();
}
return arc;
}
FArchive &operator<< (FArchive &arc, usercmd_t &cmd)
FSerializer &Serialize(FSerializer &arc, const char *key, usercmd_t &cmd, usercmd_t *def)
{
BYTE bytes[256];
BYTE *stream = bytes;
if (arc.IsStoring ())
// This used packed data with the old serializer but that's totally counterproductive when
// having a text format that is human-readable. So this compression has been undone here.
// The few bytes of file size it saves are not worth the obfuscation.
if (arc.BeginObject(key))
{
BYTE len = PackUserCmd (&cmd, NULL, &stream);
arc << len;
arc.Write (bytes, len);
}
else
{
BYTE len;
arc << len;
arc.Read (bytes, len);
UnpackUserCmd (&cmd, NULL, &stream);
arc("buttons", cmd.buttons)
("pitch", cmd.pitch)
("yaw", cmd.yaw)
("roll", cmd.roll)
("forwardmove", cmd.forwardmove)
("sidemove", cmd.sidemove)
("upmove", cmd.upmove)
.EndObject();
}
return arc;
}

View file

@ -72,10 +72,6 @@ struct usercmd_t
short upmove;
};
class FArchive;
FArchive &operator<< (FArchive &arc, usercmd_t &cmd);
// When transmitted, the above message is preceded by a byte
// indicating which fields are actually present in the message.
enum

View file

@ -35,7 +35,4 @@ struct ticcmd_t
SWORD consistancy; // checks for net game
};
FArchive &operator<< (FArchive &arc, ticcmd_t &cmd);
#endif // __D_TICCMD_H__

View file

@ -48,7 +48,7 @@
#include "g_level.h"
#include "colormatcher.h"
#include "b_bot.h"
#include "farchive.h"
#include "serializer.h"
FDecalLib DecalLibrary;
@ -113,7 +113,7 @@ struct DDecalThinker : public DThinker
HAS_OBJECT_POINTERS
public:
DDecalThinker (DBaseDecal *decal) : DThinker (STAT_DECALTHINKER), TheDecal (decal) {}
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
TObjPtr<DBaseDecal> TheDecal;
protected:
DDecalThinker () : DThinker (STAT_DECALTHINKER) {}
@ -123,10 +123,10 @@ IMPLEMENT_POINTY_CLASS (DDecalThinker)
DECLARE_POINTER (TheDecal)
END_POINTERS
void DDecalThinker::Serialize (FArchive &arc)
void DDecalThinker::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << TheDecal;
arc("thedecal", TheDecal);
}
struct FDecalFaderAnim : public FDecalAnimator
@ -143,7 +143,7 @@ class DDecalFader : public DDecalThinker
DECLARE_CLASS (DDecalFader, DDecalThinker)
public:
DDecalFader (DBaseDecal *decal) : DDecalThinker (decal) {}
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
int TimeToStartDecay;
@ -168,7 +168,7 @@ class DDecalColorer : public DDecalThinker
DECLARE_CLASS (DDecalColorer, DDecalThinker)
public:
DDecalColorer (DBaseDecal *decal) : DDecalThinker (decal) {}
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
int TimeToStartDecay;
@ -194,7 +194,7 @@ class DDecalStretcher : public DDecalThinker
DECLARE_CLASS (DDecalStretcher, DDecalThinker)
public:
DDecalStretcher (DBaseDecal *decal) : DDecalThinker (decal) {}
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
int TimeToStart;
@ -225,7 +225,7 @@ class DDecalSlider : public DDecalThinker
DECLARE_CLASS (DDecalSlider, DDecalThinker)
public:
DDecalSlider (DBaseDecal *decal) : DDecalThinker (decal) {}
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
int TimeToStart;
@ -1153,10 +1153,12 @@ FDecalAnimator::~FDecalAnimator ()
IMPLEMENT_CLASS (DDecalFader)
void DDecalFader::Serialize (FArchive &arc)
void DDecalFader::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << TimeToStartDecay << TimeToEndDecay << StartTrans;
arc("starttime", TimeToStartDecay)
("endtime", TimeToEndDecay)
("starttrans", StartTrans);
}
void DDecalFader::Tick ()
@ -1200,18 +1202,18 @@ DThinker *FDecalFaderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
IMPLEMENT_CLASS (DDecalStretcher)
void DDecalStretcher::Serialize (FArchive &arc)
void DDecalStretcher::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << TimeToStart
<< TimeToStop
<< GoalX
<< StartX
<< bStretchX
<< GoalY
<< StartY
<< bStretchY
<< bStarted;
arc("starttime", TimeToStart)
("endtime", TimeToStop)
("goalx", GoalX)
("startx", StartX)
("stretchx", bStretchX)
("goaly", GoalY)
("starty", StartY)
("stretchy", bStretchY)
("started", bStarted);
}
DThinker *FDecalStretcherAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
@ -1288,16 +1290,14 @@ void DDecalStretcher::Tick ()
IMPLEMENT_CLASS (DDecalSlider)
void DDecalSlider::Serialize (FArchive &arc)
void DDecalSlider::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << TimeToStart
<< TimeToStop
/*<< DistX*/
<< DistY
/*<< StartX*/
<< StartY
<< bStarted;
arc("starttime", TimeToStart)
("endtime", TimeToStop)
("disty", DistY)
("starty", StartY)
("started", bStarted);
}
DThinker *FDecalSliderAnim::CreateThinker (DBaseDecal *actor, side_t *wall) const
@ -1371,10 +1371,13 @@ FDecalAnimator *FDecalLib::FindAnimator (const char *name)
IMPLEMENT_CLASS (DDecalColorer)
void DDecalColorer::Serialize (FArchive &arc)
void DDecalColorer::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << TimeToStartDecay << TimeToEndDecay << StartColor << GoalColor;
arc("starttime", TimeToStartDecay)
("endtime", TimeToEndDecay)
("startcolor", StartColor)
("goalcolor", GoalColor);
}
void DDecalColorer::Tick ()

View file

@ -47,7 +47,13 @@
#include "stats.h"
#include "a_sharedglobal.h"
#include "dsectoreffect.h"
#include "farchive.h"
#include "serializer.h"
//==========================================================================
//
//
//
//==========================================================================
ClassReg DObject::RegistrationInfo =
{
@ -61,6 +67,12 @@ ClassReg DObject::RegistrationInfo =
};
_DECLARE_TI(DObject)
//==========================================================================
//
//
//
//==========================================================================
CCMD (dumpactors)
{
const char *const filters[32] =
@ -95,6 +107,12 @@ CCMD (dumpactors)
}
}
//==========================================================================
//
//
//
//==========================================================================
CCMD (dumpclasses)
{
// This is by no means speed-optimized. But it's an informational console
@ -234,6 +252,12 @@ CCMD (dumpclasses)
Printf ("%d classes shown, %d omitted\n", shown, omitted);
}
//==========================================================================
//
//
//
//==========================================================================
void DObject::InPlaceConstructor (void *mem)
{
new ((EInPlace *)mem) DObject;
@ -255,6 +279,12 @@ DObject::DObject (PClass *inClass)
GC::Root = this;
}
//==========================================================================
//
//
//
//==========================================================================
DObject::~DObject ()
{
if (!PClass::bShutdown)
@ -304,11 +334,23 @@ DObject::~DObject ()
}
}
//==========================================================================
//
//
//
//==========================================================================
void DObject::Destroy ()
{
ObjectFlags = (ObjectFlags & ~OF_Fixed) | OF_EuthanizeMe;
}
//==========================================================================
//
//
//
//==========================================================================
size_t DObject::PropagateMark()
{
const PClass *info = GetClass();
@ -330,6 +372,12 @@ size_t DObject::PropagateMark()
return 0;
}
//==========================================================================
//
//
//
//==========================================================================
size_t DObject::PointerSubstitution (DObject *old, DObject *notOld)
{
const PClass *info = GetClass();
@ -352,6 +400,12 @@ size_t DObject::PointerSubstitution (DObject *old, DObject *notOld)
return changed;
}
//==========================================================================
//
//
//
//==========================================================================
size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
{
DObject *probe;
@ -417,70 +471,41 @@ size_t DObject::StaticPointerSubstitution (DObject *old, DObject *notOld)
return changed;
}
void DObject::SerializeUserVars(FArchive &arc)
//==========================================================================
//
//
//
//==========================================================================
void DObject::SerializeUserVars(FSerializer &arc)
{
PSymbolTable *symt;
FName varname;
DWORD count, j;
int *varloc = NULL;
symt = &GetClass()->Symbols;
if (arc.IsStoring())
if (arc.isWriting())
{
// Write all fields that aren't serialized by native code.
GetClass()->WriteValue(arc, this);
}
else if (SaveVersion >= 4535)
{
GetClass()->ReadValue(arc, this);
GetClass()->WriteAllFields(arc, this);
}
else
{ // Old version that only deals with ints
// Read user variables until 'None' is encountered.
arc << varname;
while (varname != NAME_None)
{
PField *var = dyn_cast<PField>(symt->FindSymbol(varname, true));
DWORD wanted = 0;
if (var != NULL && !(var->Flags & VARF_Native))
{
PType *type = var->Type;
PArray *arraytype = dyn_cast<PArray>(type);
if (arraytype != NULL)
{
wanted = arraytype->ElementCount;
type = arraytype->ElementType;
}
else
{
wanted = 1;
}
assert(type == TypeSInt32);
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->Offset);
}
count = arc.ReadCount();
for (j = 0; j < MIN(wanted, count); ++j)
{
arc << varloc[j];
}
if (wanted < count)
{
// Ignore remaining values from archive.
for (; j < count; ++j)
{
int foo;
arc << foo;
}
}
arc << varname;
}
{
GetClass()->ReadAllFields(arc, this);
}
}
void DObject::Serialize (FArchive &arc)
//==========================================================================
//
//
//
//==========================================================================
void DObject::Serialize(FSerializer &arc)
{
int fresh = ObjectFlags & OF_JustSpawned;
int freshdef = 0;
arc("justspawned", fresh, freshdef);
if (arc.isReading())
{
ObjectFlags |= fresh;
}
ObjectFlags |= OF_SerialSuccess;
}

View file

@ -39,7 +39,7 @@
class PClass;
class FArchive;
class FSerializer;
class DObject;
/*
@ -413,16 +413,12 @@ public:
return GC::ReadBarrier(p) == u;
}
template<class U> friend inline FArchive &operator<<(FArchive &arc, TObjPtr<U> &o);
template<class U> friend inline void GC::Mark(TObjPtr<U> &obj);
template<class U> friend FSerializer &Serialize(FSerializer &arc, const char *key, TObjPtr<U> &value, TObjPtr<U> *);
friend class DObject;
};
template<class T> inline FArchive &operator<<(FArchive &arc, TObjPtr<T> &o)
{
return arc << o.p;
}
// Use barrier_cast instead of static_cast when you need to cast
// the contents of a TObjPtr to a related type.
template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
@ -463,8 +459,9 @@ public:
inline bool IsKindOf (const PClass *base) const;
inline bool IsA (const PClass *type) const;
void SerializeUserVars(FArchive &arc);
virtual void Serialize (FArchive &arc);
void SerializeUserVars(FSerializer &arc);
virtual void Serialize(FSerializer &arc);
void ClearClass()
{
Class = NULL;

View file

@ -39,7 +39,7 @@
#include "dobject.h"
#include "i_system.h"
#include "farchive.h"
#include "serializer.h"
#include "actor.h"
#include "templates.h"
#include "autosegs.h"
@ -47,6 +47,7 @@
#include "a_pickups.h"
#include "a_weaponpiece.h"
#include "d_player.h"
#include "doomerrors.h"
#include "fragglescript/t_fs.h"
// MACROS ------------------------------------------------------------------
@ -390,7 +391,7 @@ bool PType::VisitedNodeSet::Check(const PType *node)
//
//==========================================================================
void PType::WriteValue(FArchive &ar, const void *addr) const
void PType::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
assert(0 && "Cannot write value for this type");
}
@ -401,104 +402,12 @@ void PType::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
bool PType::ReadValue(FArchive &ar, void *addr) const
bool PType::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
assert(0 && "Cannot read value for this type");
SkipValue(ar);
return false;
}
//==========================================================================
//
// PType :: SkipValue STATIC
//
//==========================================================================
void PType::SkipValue(FArchive &ar)
{
BYTE tag;
ar << tag;
SkipValue(ar, tag);
}
void PType::SkipValue(FArchive &ar, int tag)
{
assert(ar.IsLoading() && "SkipValue passed an archive that is writing");
BYTE buff[8];
switch (tag)
{
case VAL_Zero: case VAL_One:
break;
case VAL_Int8: case VAL_UInt8:
ar.Read(buff, 1);
break;
case VAL_Int16: case VAL_UInt16:
ar.Read(buff, 2);
break;
case VAL_Int32: case VAL_UInt32: case VAL_Float32:
ar.Read(buff, 4);
break;
case VAL_Int64: case VAL_UInt64: case VAL_Float64:
ar.Read(buff, 8);
break;
case VAL_Name:
ar.ReadName();
break;
case VAL_Object:
{
DObject *skipper;
ar << skipper;
break;
}
case VAL_State:
{
FState *skipper;
ar << skipper;
break;
}
case VAL_String:
{
FString skipper;
ar << skipper;
break;
}
case VAL_Array:
{
DWORD count = ar.ReadCount();
while (count-- > 0)
{
SkipValue(ar);
}
break;
}
case VAL_Struct:
{
const char *label;
for (label = ar.ReadName(); label != NULL; label = ar.ReadName())
{
SkipValue(ar);
}
break;
}
case VAL_Class:
{
PClass *type;
for (ar.UserReadClass(type); type != NULL; ar.UserReadClass(type))
{
SkipValue(ar, VAL_Struct);
}
break;
}
}
}
//==========================================================================
//
// PType :: SetDefaultValue
@ -805,116 +714,41 @@ PInt::PInt(unsigned int size, bool unsign)
//
// PInt :: WriteValue
//
// Write the value using the minimum byte size needed to represent it. This
// means that the value as written is not necessarily of the same type as
// stored, but the signedness information is preserved.
//
//==========================================================================
void PInt::WriteValue(FArchive &ar, const void *addr) const
void PInt::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
BYTE bval;
// The process for bytes is the same whether signed or unsigned, since
// they can't be compacted into a representation with fewer bytes.
if (Size == 1)
if (Size == 8 && Unsigned)
{
bval = *(BYTE *)addr;
}
else if (Unsigned)
{
unsigned val;
if (Size == 8)
{
QWORD qval = *(QWORD *)addr;
if (qval & 0xFFFFFFFF00000000llu)
{ // Value needs 64 bits
ar.WriteByte(VAL_UInt64);
ar.WriteInt64(qval);
return;
}
// Value can fit in 32 bits or less
val = (unsigned)qval;
goto check_u32;
}
else if (Size == 4)
{
val = *(DWORD *)addr;
check_u32: if (val & 0xFFFF0000u)
{ // Value needs 32 bits
ar.WriteByte(VAL_UInt32);
ar.WriteInt32(val);
return;
}
// Value can fit in 16 bits or less
goto check_u16;
}
else// if (Size == 2)
{
val = *(WORD *)addr;
check_u16: if (val & 0xFFFFFF00u)
{ // Value needs 16 bits
ar.WriteByte(VAL_UInt16);
ar.WriteInt16(val);
return;
}
// Value can fit in 8 bits
bval = (BYTE)val;
}
}
else // Signed
{
int val;
if (Size == 8)
{
SQWORD qval = *(SQWORD *)addr;
INT_MIN;
if (qval < (-0x7FFFFFFF - 1) || qval > 0x7FFFFFFF)
{ // Value needs 64 bits
ar.WriteByte(VAL_Int64);
ar.WriteInt64(qval);
return;
}
// Value can fit in 32 bits or less
val = (int)qval;
goto check_s32;
}
else if (Size == 4)
{
val = *(SDWORD *)addr;
check_s32: if (val < -0x8000 || val > 0x7FFF)
{ // Value needs 32 bits
ar.WriteByte(VAL_Int32);
ar.WriteInt32(val);
return;
}
// Value can fit in 16 bits or less
goto check_s16;
}
else// if (Size == 2)
{
val = *(SWORD *)addr;
check_s16: if (val < -0x80 || val > 0x7F)
{ // Value needs 16 bits
ar.WriteByte(VAL_Int16);
ar.WriteInt16(val);
return;
}
// Value can fit in 8 bits
bval = (BYTE)val;
}
}
// If we get here, the value fits in a byte. Values of 0 and 1 are
// optimized away into the tag so they don't require any extra space
// to store.
if (bval & 0xFE)
{
BYTE out[2] = { Unsigned ? VAL_UInt8 : VAL_Int8, bval };
ar.Write(out, 2);
// this is a special case that cannot be represented by an int64_t.
uint64_t val = *(uint64_t*)addr;
ar(key, val);
}
else
{
ar.WriteByte(VAL_Zero + bval);
int64_t val;
switch (Size)
{
case 1:
val = Unsigned ? *(uint8_t*)addr : *(int8_t*)addr;
break;
case 2:
val = Unsigned ? *(uint16_t*)addr : *(int16_t*)addr;
break;
case 4:
val = Unsigned ? *(uint32_t*)addr : *(int32_t*)addr;
break;
case 8:
val = *(int64_t*)addr;
break;
default:
return; // something invalid
}
ar(key, val);
}
}
@ -924,47 +758,37 @@ check_s16: if (val < -0x80 || val > 0x7F)
//
//==========================================================================
bool PInt::ReadValue(FArchive &ar, void *addr) const
bool PInt::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
union
{
QWORD uval;
SQWORD sval;
};
BYTE tag;
union
{
BYTE val8;
WORD val16;
DWORD val32;
float single;
double dbl;
};
NumericValue val;
ar << tag;
switch (tag)
{
case VAL_Zero: uval = 0; break;
case VAL_One: uval = 1; break;
case VAL_Int8: ar << val8; sval = (SBYTE)val8; break;
case VAL_UInt8: ar << val8; uval = val8; break;
case VAL_Int16: ar << val16; sval = (SWORD)val16; break;
case VAL_UInt16: ar << val16; uval = val16; break;
case VAL_Int32: ar << val32; sval = (SDWORD)val32; break;
case VAL_UInt32: ar << val32; uval = val32; break;
case VAL_Int64: ar << sval; break;
case VAL_UInt64: ar << uval; break;
case VAL_Float32: ar << single; sval = (SQWORD)single; break;
case VAL_Float64: ar << dbl; sval = (SQWORD)dbl; break;
default: SkipValue(ar, tag); return false; // Incompatible type
}
ar(key, val);
if (val.type == NumericValue::NM_invalid) return false; // not found or usable
if (val.type == NumericValue::NM_float) val.signedval = (int64_t)val.floatval;
// No need to check the unsigned state here. Downcasting to smaller types will yield the same result for both.
switch (Size)
{
case 1: *(BYTE *)addr = (BYTE)uval; break;
case 2: *(WORD *)addr = (WORD)uval; break;
case 4: *(DWORD *)addr = (DWORD)uval; break;
case 8: *(QWORD *)addr = uval; break;
case 1:
*(uint8_t*)addr = (uint8_t)val.signedval;
break;
case 2:
*(uint16_t*)addr = (uint16_t)val.signedval;
break;
case 4:
*(uint32_t*)addr = (uint32_t)val.signedval;
break;
case 8:
*(uint64_t*)addr = (uint64_t)val.signedval;
break;
default:
return false; // something invalid
}
return true;
}
@ -1259,28 +1083,16 @@ void PFloat::SetSymbols(const PFloat::SymbolInitI *sym, size_t count)
//
//==========================================================================
void PFloat::WriteValue(FArchive &ar, const void *addr) const
void PFloat::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
float singleprecision;
if (Size == 8)
{
// If it can be written as single precision without information
// loss, then prefer that over writing a full-sized double.
double doubleprecision = *(double *)addr;
singleprecision = (float)doubleprecision;
if (singleprecision != doubleprecision)
{
ar.WriteByte(VAL_Float64);
ar << doubleprecision;
return;
}
ar(key, *(double*)addr);
}
else
{
singleprecision = *(float *)addr;
ar(key, *(float*)addr);
}
ar.WriteByte(VAL_Float32);
ar << singleprecision;
}
//==========================================================================
@ -1289,60 +1101,26 @@ void PFloat::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
static bool ReadValueDbl(FArchive &ar, double *addr, unsigned tag)
bool PFloat::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
double val;
union
{
BYTE val8;
WORD val16;
DWORD val32;
QWORD val64;
fixed_t fix;
float single;
angle_t ang;
};
NumericValue val;
switch (tag)
ar(key, val);
if (val.type == NumericValue::NM_invalid) return false; // not found or usable
else if (val.type == NumericValue::NM_signed) val.floatval = (double)val.signedval;
else if (val.type == NumericValue::NM_unsigned) val.floatval = (double)val.unsignedval;
if (Size == 8)
{
case VAL_Zero: val = 0; break;
case VAL_One: val = 1; break;
case VAL_Int8: ar << val8; val = (SBYTE)val8; break;
case VAL_UInt8: ar << val8; val = val8; break;
case VAL_Int16: ar << val16; val = (SWORD)val16; break;
case VAL_UInt16: ar << val16; val = val16; break;
case VAL_Int32: ar << val32; val = (SDWORD)val32; break;
case VAL_UInt32: ar << val32; val = val32; break;
case VAL_Int64: ar << val64; val = (double)(SQWORD)val64; break;
case VAL_UInt64: ar << val64; val = (double)val64; break;
case VAL_Float32: ar << single; val = single; break;
case VAL_Float64: ar << val; break;
default: PType::SkipValue(ar, tag); return false; // Incompatible type
*(double*)addr = val.floatval;
}
else
{
*(float*)addr = (float)val.floatval;
}
*(double *)addr = val;
return true;
}
bool PFloat::ReadValue(FArchive &ar, void *addr) const
{
BYTE tag;
ar << tag;
double val;
if (ReadValueDbl(ar, &val, tag))
{
if (Size == 4)
{
*(float *)addr = (float)val;
}
else
{
*(double *)addr = val;
}
return true;
}
return false;
}
//==========================================================================
//
// PFloat :: SetValue
@ -1482,10 +1260,9 @@ int PString::GetRegType() const
//
//==========================================================================
void PString::WriteValue(FArchive &ar, const void *addr) const
void PString::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
ar.WriteByte(VAL_String);
ar.WriteString(*(const FString *)addr);
ar(key, *(FString*)addr);
}
//==========================================================================
@ -1494,25 +1271,19 @@ void PString::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
bool PString::ReadValue(FArchive &ar, void *addr) const
bool PString::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
BYTE tag;
ar << tag;
if (tag == VAL_String)
const char *cptr;
ar.StringPtr(key, cptr);
if (cptr == nullptr)
{
ar << *(FString *)addr;
}
else if (tag == VAL_Name)
{
const char *str = ar.ReadName();
*(FString *)addr = str;
return false;
}
else
{
SkipValue(ar, tag);
return false;
*(FString*)addr = cptr;
return true;
}
return true;
}
//==========================================================================
@ -1574,10 +1345,10 @@ PName::PName()
//
//==========================================================================
void PName::WriteValue(FArchive &ar, const void *addr) const
void PName::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
ar.WriteByte(VAL_Name);
ar.WriteName(((const FName *)addr)->GetChars());
const char *cptr = ((const FName*)addr)->GetChars();
ar.StringPtr(key, cptr);
}
//==========================================================================
@ -1586,26 +1357,19 @@ void PName::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
bool PName::ReadValue(FArchive &ar, void *addr) const
bool PName::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
BYTE tag;
ar << tag;
if (tag == VAL_Name)
const char *cptr;
ar.StringPtr(key, cptr);
if (cptr == nullptr)
{
*(FName *)addr = FName(ar.ReadName());
}
else if (tag == VAL_String)
{
FString str;
ar << str;
*(FName *)addr = FName(str);
return false;
}
else
{
SkipValue(ar, tag);
return false;
*(FName*)addr = FName(cptr);
return true;
}
return true;
}
/* PSound *****************************************************************/
@ -1630,10 +1394,10 @@ PSound::PSound()
//
//==========================================================================
void PSound::WriteValue(FArchive &ar, const void *addr) const
void PSound::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
ar.WriteByte(VAL_Name);
ar.WriteName(*(const FSoundID *)addr);
const char *cptr = *(const FSoundID *)addr;
ar.StringPtr(key, cptr);
}
//==========================================================================
@ -1642,28 +1406,19 @@ void PSound::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
bool PSound::ReadValue(FArchive &ar, void *addr) const
bool PSound::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
BYTE tag;
ar << tag;
if (tag == VAL_Name)
const char *cptr;
ar.StringPtr(key, cptr);
if (cptr == nullptr)
{
const char *str = ar.ReadName();
*(FSoundID *)addr = FSoundID(str);
}
else if (tag == VAL_String)
{
FString str;
ar << str;
*(FSoundID *)addr = FSoundID(str);
return false;
}
else
{
SkipValue(ar, tag);
return false;
*(FSoundID *)addr = FSoundID(cptr);
return true;
}
return true;
}
/* PColor *****************************************************************/
@ -1736,10 +1491,9 @@ int PStatePointer::GetRegType() const
//
//==========================================================================
void PStatePointer::WriteValue(FArchive &ar, const void *addr) const
void PStatePointer::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
ar.WriteByte(VAL_State);
ar << *(FState **)addr;
ar(key, *(FState **)addr);
}
//==========================================================================
@ -1748,17 +1502,11 @@ void PStatePointer::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
bool PStatePointer::ReadValue(FArchive &ar, void *addr) const
bool PStatePointer::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
BYTE tag;
ar << tag;
if (tag == VAL_State)
{
ar << *(FState **)addr;
return true;
}
SkipValue(ar, tag);
return false;
bool res = false;
::Serialize(ar, key, *(FState **)addr, nullptr, &res);
return res;
}
/* PPointer ***************************************************************/
@ -1854,12 +1602,11 @@ void PPointer::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
//
//==========================================================================
void PPointer::WriteValue(FArchive &ar, const void *addr) const
void PPointer::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
if (PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
{
ar.WriteByte(VAL_Object);
ar << *(DObject **)addr;
ar(key, *(DObject **)addr);
}
else
{
@ -1874,16 +1621,14 @@ void PPointer::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
bool PPointer::ReadValue(FArchive &ar, void *addr) const
bool PPointer::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
BYTE tag;
ar << tag;
if (tag == VAL_Object && PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
if (PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
{
ar << *(DObject **)addr;
return true;
bool res = false;
::Serialize(ar, key, *(DObject **)addr, nullptr, &res);
return res;
}
SkipValue(ar, tag);
return false;
}
@ -2098,15 +1843,17 @@ void PArray::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
//
//==========================================================================
void PArray::WriteValue(FArchive &ar, const void *addr) const
void PArray::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
ar.WriteByte(VAL_Array);
ar.WriteCount(ElementCount);
const BYTE *addrb = (const BYTE *)addr;
for (unsigned i = 0; i < ElementCount; ++i)
if (ar.BeginArray(key))
{
ElementType->WriteValue(ar, addrb);
addrb += ElementSize;
const BYTE *addrb = (const BYTE *)addr;
for (unsigned i = 0; i < ElementCount; ++i)
{
ElementType->WriteValue(ar, nullptr, addrb);
addrb += ElementSize;
}
ar.EndArray();
}
}
@ -2116,34 +1863,27 @@ void PArray::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
bool PArray::ReadValue(FArchive &ar, void *addr) const
bool PArray::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
bool readsomething = false;
BYTE tag;
ar << tag;
if (tag == VAL_Array)
if (ar.BeginArray(key))
{
unsigned count = ar.ReadCount();
unsigned i;
bool readsomething = false;
unsigned count = ar.ArraySize();
unsigned loop = MIN(count, ElementCount);
BYTE *addrb = (BYTE *)addr;
for (i = 0; i < MIN(count, ElementCount); ++i)
for(unsigned i=0;i<loop;i++)
{
readsomething |= ElementType->ReadValue(ar, addrb);
readsomething |= ElementType->ReadValue(ar, nullptr, addrb);
addrb += ElementSize;
}
if (i < ElementCount)
if (loop < count)
{
DPrintf(DMSG_WARNING, "Array on disk (%u) is bigger than in memory (%u)\n",
count, ElementCount);
for (; i < ElementCount; ++i)
{
SkipValue(ar);
}
}
ar.EndArray();
return readsomething;
}
SkipValue(ar, tag);
return false;
}
@ -2437,10 +2177,13 @@ void PStruct::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset
//
//==========================================================================
void PStruct::WriteValue(FArchive &ar, const void *addr) const
void PStruct::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
ar.WriteByte(VAL_Struct);
WriteFields(ar, addr, Fields);
if (ar.BeginObject(key))
{
WriteFields(ar, addr, Fields);
ar.EndObject();
}
}
//==========================================================================
@ -2449,16 +2192,15 @@ void PStruct::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
bool PStruct::ReadValue(FArchive &ar, void *addr) const
bool PStruct::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
BYTE tag;
ar << tag;
if (tag == VAL_Struct)
if (ar.BeginObject(key))
{
return ReadFields(ar, addr);
bool ret = ReadFields(ar, addr);
ar.EndObject();
return ret;
}
SkipValue(ar, tag);
return true;
return false;
}
//==========================================================================
@ -2467,7 +2209,7 @@ bool PStruct::ReadValue(FArchive &ar, void *addr) const
//
//==========================================================================
void PStruct::WriteFields(FArchive &ar, const void *addr, const TArray<PField *> &fields)
void PStruct::WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields)
{
for (unsigned i = 0; i < fields.Size(); ++i)
{
@ -2475,11 +2217,9 @@ void PStruct::WriteFields(FArchive &ar, const void *addr, const TArray<PField *>
// Skip fields with native serialization
if (!(field->Flags & VARF_Native))
{
ar.WriteName(field->SymbolName);
field->Type->WriteValue(ar, (const BYTE *)addr + field->Offset);
field->Type->WriteValue(ar, field->SymbolName.GetChars(), (const BYTE *)addr + field->Offset);
}
}
ar.WriteName(NULL);
}
//==========================================================================
@ -2488,36 +2228,33 @@ void PStruct::WriteFields(FArchive &ar, const void *addr, const TArray<PField *>
//
//==========================================================================
bool PStruct::ReadFields(FArchive &ar, void *addr) const
bool PStruct::ReadFields(FSerializer &ar, void *addr) const
{
bool readsomething = false;
const char *label = ar.ReadName();
if (label == NULL)
{ // If there is nothing to restore, we count it as success.
return true;
}
for (; label != NULL; label = ar.ReadName())
bool foundsomething = false;
const char *label;
while ((label = ar.GetKey()))
{
foundsomething = true;
const PSymbol *sym = Symbols.FindSymbol(FName(label, true), true);
if (sym == NULL)
{
DPrintf(DMSG_ERROR, "Cannot find field %s in %s\n",
label, TypeName.GetChars());
SkipValue(ar);
}
else if (!sym->IsKindOf(RUNTIME_CLASS(PField)))
{
DPrintf(DMSG_ERROR, "Symbol %s in %s is not a field\n",
label, TypeName.GetChars());
SkipValue(ar);
}
else
{
readsomething |= static_cast<const PField *>(sym)->Type->ReadValue(ar,
readsomething |= static_cast<const PField *>(sym)->Type->ReadValue(ar, nullptr,
(BYTE *)addr + static_cast<const PField *>(sym)->Offset);
}
}
return readsomething;
return readsomething || !foundsomething;
}
//==========================================================================
@ -2741,7 +2478,7 @@ END_POINTERS
//
//==========================================================================
static void RecurseWriteFields(const PClass *type, FArchive &ar, const void *addr)
static void RecurseWriteFields(const PClass *type, FSerializer &ar, const void *addr)
{
if (type != NULL)
{
@ -2755,19 +2492,33 @@ static void RecurseWriteFields(const PClass *type, FArchive &ar, const void *add
// a more-derived class has variables that shadow a less-
// derived class. Whether or not that is a language feature
// that will actually be allowed remains to be seen.
ar.UserWriteClass(const_cast<PClass *>(type));
PStruct::WriteFields(ar, addr, type->Fields);
FString key;
key.Format("class:%s", type->TypeName.GetChars());
if (ar.BeginObject(key.GetChars()))
{
PStruct::WriteFields(ar, addr, type->Fields);
ar.EndObject();
}
break;
}
}
}
}
void PClass::WriteValue(FArchive &ar, const void *addr) const
void PClass::WriteValue(FSerializer &ar, const char *key,const void *addr) const
{
if (ar.BeginObject(key))
{
RecurseWriteFields(this, ar, addr);
ar.EndObject();
}
}
// Same as WriteValue, but does not create a new object in the serializer
// This is so that user variables do not contain unnecessary subblocks.
void PClass::WriteAllFields(FSerializer &ar, const void *addr) const
{
ar.WriteByte(VAL_Class);
RecurseWriteFields(this, ar, addr);
ar.UserWriteClass(NULL);
}
//==========================================================================
@ -2776,20 +2527,40 @@ void PClass::WriteValue(FArchive &ar, const void *addr) const
//
//==========================================================================
bool PClass::ReadValue(FArchive &ar, void *addr) const
bool PClass::ReadValue(FSerializer &ar, const char *key, void *addr) const
{
BYTE tag;
ar << tag;
if (tag != VAL_Class)
if (ar.BeginObject(key))
{
SkipValue(ar, tag);
bool ret = ReadAllFields(ar, addr);
ar.EndObject();
return ret;
}
return true;
}
bool PClass::ReadAllFields(FSerializer &ar, void *addr) const
{
bool readsomething = false;
bool foundsomething = false;
const char *key;
key = ar.GetKey();
if (strcmp(key, "classtype"))
{
// this does not represent a DObject
Printf(TEXTCOLOR_RED "trying to read user variables but got a non-object (first key is '%s')", key);
ar.mErrors++;
return false;
}
else
while ((key = ar.GetKey()))
{
bool readsomething = false;
PClass *type;
for (ar.UserReadClass(type); type != NULL; ar.UserReadClass(type))
if (strncmp(key, "class:", 6))
{
// We have read all user variable blocks.
break;
}
foundsomething = true;
PClass *type = PClass::FindClass(key + 6);
if (type != nullptr)
{
// Only read it if the type is related to this one.
const PClass *parent;
@ -2800,19 +2571,27 @@ bool PClass::ReadValue(FArchive &ar, void *addr) const
break;
}
}
if (parent != NULL)
if (parent != nullptr)
{
readsomething |= type->ReadFields(ar, addr);
if (ar.BeginObject(nullptr))
{
readsomething |= type->ReadFields(ar, addr);
ar.EndObject();
}
}
else
{
DPrintf(DMSG_ERROR, "Unknown superclass %s of class %s\n",
type->TypeName.GetChars(), TypeName.GetChars());
SkipValue(ar, VAL_Struct);
}
}
return readsomething;
else
{
DPrintf(DMSG_ERROR, "Unknown superclass %s of class %s\n",
key+6, TypeName.GetChars());
}
}
return readsomething || !foundsomething;
}
//==========================================================================

View file

@ -193,15 +193,11 @@ public:
// a tag indicating its type. The tag is there so that variable types can be changed
// without completely breaking savegames, provided that the change isn't between
// totally unrelated types.
virtual void WriteValue(FArchive &ar, const void *addr) const;
virtual void WriteValue(FSerializer &ar, const char *key,const void *addr) const;
// Returns true if the stored value was compatible. False otherwise.
// If the value was incompatible, then the memory at *addr is unchanged.
virtual bool ReadValue(FArchive &ar, void *addr) const;
// Skips over a value written with WriteValue
static void SkipValue(FArchive &ar);
static void SkipValue(FArchive &ar, int tag);
virtual bool ReadValue(FSerializer &ar, const char *key,void *addr) const;
// Sets the default value for this type at (base + offset)
// If the default value is binary 0, then this function doesn't need
@ -354,8 +350,8 @@ class PInt : public PBasicType
public:
PInt(unsigned int size, bool unsign);
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
@ -383,8 +379,8 @@ class PFloat : public PBasicType
public:
PFloat(unsigned int size);
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
@ -421,8 +417,8 @@ public:
virtual int GetRegType() const;
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
@ -436,8 +432,8 @@ class PName : public PInt
public:
PName();
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
};
class PSound : public PInt
@ -446,8 +442,8 @@ class PSound : public PInt
public:
PSound();
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
};
class PColor : public PInt
@ -465,8 +461,8 @@ class PStatePointer : public PBasicType
public:
PStatePointer();
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
virtual int GetStoreOp() const;
virtual int GetLoadOp() const;
@ -489,8 +485,8 @@ public:
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
protected:
PPointer();
@ -559,8 +555,8 @@ public:
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const override;
@ -622,12 +618,12 @@ public:
size_t PropagateMark();
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) const override;
static void WriteFields(FArchive &ar, const void *addr, const TArray<PField *> &fields);
bool ReadFields(FArchive &ar, void *addr) const;
static void WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields);
bool ReadFields(FSerializer &ar, void *addr) const;
protected:
PStruct();
};
@ -692,8 +688,10 @@ public:
typedef PClassClass MetaClass;
MetaClass *GetClass() const;
void WriteValue(FArchive &ar, const void *addr) const override;
bool ReadValue(FArchive &ar, void *addr) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
void WriteAllFields(FSerializer &ar, const void *addr) const;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
bool ReadAllFields(FSerializer &ar, void *addr) const;
virtual void DeriveData(PClass *newclass) {}
static void StaticInit();

View file

@ -339,7 +339,6 @@ struct mapthinghexen_t
BYTE args[5];
};
class FArchive;
struct FDoomEdEntry;
// Internal representation of a mapthing

View file

@ -206,13 +206,11 @@ struct PalEntry
#endif
};
class FArchive;
class PClassInventory;
class FTextureID
{
friend class FTextureManager;
friend FArchive &operator<< (FArchive &arc, FTextureID &tex);
friend FTextureID GetHUDIcon(PClassInventory *cls);
friend void R_InitSpriteDefs();

View file

@ -28,7 +28,7 @@
#include "p_3dmidtex.h"
#include "r_data/r_interpolate.h"
#include "statnums.h"
#include "farchive.h"
#include "serializer.h"
#include "doomstat.h"
IMPLEMENT_CLASS (DSectorEffect)
@ -64,10 +64,10 @@ DSectorEffect::DSectorEffect (sector_t *sector)
m_Sector = sector;
}
void DSectorEffect::Serialize (FArchive &arc)
void DSectorEffect::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << m_Sector;
arc("sector", m_Sector);
}
IMPLEMENT_POINTY_CLASS (DMover)
@ -90,10 +90,10 @@ void DMover::Destroy()
Super::Destroy();
}
void DMover::Serialize (FArchive &arc)
void DMover::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << interpolation;
arc("interpolation", interpolation);
}
void DMover::StopInterpolation(bool force)

View file

@ -10,7 +10,8 @@ class DSectorEffect : public DThinker
public:
DSectorEffect (sector_t *sector);
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Destroy();
sector_t *GetSector() const { return m_Sector; }
@ -32,7 +33,8 @@ protected:
private:
protected:
DMover ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Destroy();
};

View file

@ -38,7 +38,7 @@
#include "statnums.h"
#include "i_system.h"
#include "doomerrors.h"
#include "farchive.h"
#include "serializer.h"
#include "d_player.h"
@ -103,102 +103,98 @@ bool FThinkerList::IsEmpty() const
return Sentinel == NULL || Sentinel->NextThinker == NULL;
}
void DThinker::SaveList(FArchive &arc, DThinker *node)
void DThinker::SaveList(FSerializer &arc, DThinker *node)
{
if (node != NULL)
{
while (!(node->ObjectFlags & OF_Sentinel))
{
assert(node->NextThinker != NULL && !(node->NextThinker->ObjectFlags & OF_EuthanizeMe));
arc << node;
::Serialize<DThinker>(arc, nullptr, node, nullptr);
node = node->NextThinker;
}
}
}
void DThinker::SerializeAll(FArchive &arc, bool hubLoad)
//==========================================================================
//
//
//
//==========================================================================
void DThinker::SerializeThinkers(FSerializer &arc, bool hubLoad)
{
DThinker *thinker;
BYTE stat;
int statcount;
//DThinker *thinker;
//BYTE stat;
//int statcount;
int i;
// Save lists of thinkers, but not by storing the first one and letting
// the archiver catch the rest. (Which leads to buttloads of recursion
// and makes the file larger.) Instead, we explicitly save each thinker
// in sequence. When restoring an archive, we also have to maintain
// the thinker lists here instead of relying on the archiver to do it
// for us.
if (arc.IsStoring())
if (arc.isWriting())
{
for (statcount = i = 0; i <= MAX_STATNUM; i++)
{
statcount += (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty());
}
arc << statcount;
arc.BeginArray("thinkers");
for (i = 0; i <= MAX_STATNUM; i++)
{
if (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty())
{
stat = i;
arc << stat;
SaveList(arc, Thinkers[i].GetHead());
SaveList(arc, FreshThinkers[i].GetHead());
thinker = NULL;
arc << thinker; // Save a final NULL for this list
}
arc.BeginArray(nullptr);
SaveList(arc, Thinkers[i].GetHead());
SaveList(arc, FreshThinkers[i].GetHead());
arc.EndArray();
}
arc.EndArray();
}
else
{
// Prevent the constructor from inserting thinkers into a list.
bSerialOverride = true;
try
if (arc.BeginArray("thinkers"))
{
arc << statcount;
while (statcount > 0)
for (i = 0; i <= MAX_STATNUM; i++)
{
arc << stat << thinker;
while (thinker != NULL)
if (arc.BeginArray(nullptr))
{
// This may be a player stored in their ancillary list. Remove
// them first before inserting them into the new list.
if (thinker->NextThinker != NULL)
int size = arc.ArraySize();
for (int j = 0; j < size; j++)
{
thinker->Remove();
DThinker *thinker;
arc(nullptr, thinker);
if (thinker != nullptr)
{
// This may be a player stored in their ancillary list. Remove
// them first before inserting them into the new list.
if (thinker->NextThinker != nullptr)
{
thinker->Remove();
}
// Thinkers with the OF_JustSpawned flag set go in the FreshThinkers
// list. Anything else goes in the regular Thinkers list.
if (thinker->ObjectFlags & OF_EuthanizeMe)
{
// This thinker was destroyed during the loading process. Do
// not link it into any list.
}
else if (thinker->ObjectFlags & OF_JustSpawned)
{
FreshThinkers[i].AddTail(thinker);
thinker->PostSerialize();
}
else
{
Thinkers[i].AddTail(thinker);
thinker->PostSerialize();
}
}
}
// Thinkers with the OF_JustSpawned flag set go in the FreshThinkers
// list. Anything else goes in the regular Thinkers list.
if (thinker->ObjectFlags & OF_EuthanizeMe)
{
// This thinker was destroyed during the loading process. Do
// not link it in to any list.
}
else if (thinker->ObjectFlags & OF_JustSpawned)
{
FreshThinkers[stat].AddTail(thinker);
}
else
{
Thinkers[stat].AddTail(thinker);
}
arc << thinker;
arc.EndArray();
}
statcount--;
}
arc.EndArray();
}
catch (class CDoomError &)
{
bSerialOverride = false;
DestroyAllThinkers();
throw;
}
bSerialOverride = false;
}
}
//==========================================================================
//
//
//
//==========================================================================
DThinker::DThinker (int statnum) throw()
{
NextThinker = NULL;
@ -261,6 +257,10 @@ void DThinker::PostBeginPlay ()
{
}
void DThinker::PostSerialize()
{
}
DThinker *DThinker::FirstThinker (int statnum)
{
DThinker *node;
@ -332,24 +332,6 @@ void DThinker::DestroyAllThinkers ()
GC::FullGC();
}
// Destroy all thinkers except for player-controlled actors
// Players are simply removed from the list of thinkers and
// will be added back after serialization is complete.
void DThinker::DestroyMostThinkers ()
{
int i;
for (i = 0; i <= MAX_STATNUM; i++)
{
if (i != STAT_TRAVELLING)
{
DestroyMostThinkersInList (Thinkers[i], i);
DestroyMostThinkersInList (FreshThinkers[i], i);
}
}
GC::FullGC();
}
void DThinker::DestroyThinkersInList (FThinkerList &list)
{
if (list.Sentinel != NULL)
@ -364,39 +346,6 @@ void DThinker::DestroyThinkersInList (FThinkerList &list)
}
}
void DThinker::DestroyMostThinkersInList (FThinkerList &list, int stat)
{
if (stat != STAT_PLAYER)
{
DestroyThinkersInList (list);
}
else if (list.Sentinel != NULL)
{ // If it's a voodoo doll, destroy it. Otherwise, simply remove
// it from the list. G_FinishTravel() will find it later from
// a players[].mo link and destroy it then, after copying various
// information to a new player.
for (DThinker *probe = list.Sentinel->NextThinker; probe != list.Sentinel; probe = list.Sentinel->NextThinker)
{
if (!probe->IsKindOf(RUNTIME_CLASS(APlayerPawn)) || // <- should not happen
static_cast<AActor *>(probe)->player == NULL ||
static_cast<AActor *>(probe)->player->mo != probe)
{
probe->Destroy();
}
else
{
probe->Remove();
// Technically, this doesn't need to be in any list now, since
// it's only going to be found later and destroyed before ever
// needing to tick again, but by moving it to a separate list,
// I can keep my debug assertions that all thinkers are either
// euthanizing or in a list.
Thinkers[MAX_STATNUM+1].AddTail(probe);
}
}
}
}
void DThinker::RunThinkers ()
{
int i, count;
@ -473,8 +422,12 @@ void DThinker::Tick ()
size_t DThinker::PropagateMark()
{
assert(NextThinker != NULL && !(NextThinker->ObjectFlags & OF_EuthanizeMe));
assert(PrevThinker != NULL && !(PrevThinker->ObjectFlags & OF_EuthanizeMe));
// Do not choke on partially initialized objects (as happens when loading a savegame fails)
if (NextThinker != nullptr || PrevThinker != nullptr)
{
assert(NextThinker != nullptr && !(NextThinker->ObjectFlags & OF_EuthanizeMe));
assert(PrevThinker != nullptr && !(PrevThinker->ObjectFlags & OF_EuthanizeMe));
}
GC::Mark(NextThinker);
GC::Mark(PrevThinker);
return Super::PropagateMark();

View file

@ -43,6 +43,7 @@ class player_t;
struct pspdef_s;
struct FState;
class DThinker;
class FSerializer;
class FThinkerIterator;
@ -69,6 +70,7 @@ public:
virtual ~DThinker ();
virtual void Tick ();
virtual void PostBeginPlay (); // Called just before the first tick
virtual void PostSerialize();
size_t PropagateMark();
void ChangeStatNum (int statnum);
@ -76,33 +78,32 @@ public:
static void RunThinkers ();
static void RunThinkers (int statnum);
static void DestroyAllThinkers ();
static void DestroyMostThinkers ();
static void DestroyThinkersInList(int statnum)
{
DestroyThinkersInList(Thinkers[statnum]);
DestroyThinkersInList(FreshThinkers[statnum]);
}
static void SerializeAll (FArchive &arc, bool keepPlayers);
static void SerializeThinkers(FSerializer &arc, bool keepPlayers);
static void MarkRoots();
static DThinker *FirstThinker (int statnum);
static bool bSerialOverride;
private:
enum no_link_type { NO_LINK };
DThinker(no_link_type) throw();
static void DestroyThinkersInList (FThinkerList &list);
static void DestroyMostThinkersInList (FThinkerList &list, int stat);
static int TickThinkers (FThinkerList *list, FThinkerList *dest); // Returns: # of thinkers ticked
static void SaveList(FArchive &arc, DThinker *node);
static void SaveList(FSerializer &arc, DThinker *node);
void Remove();
static FThinkerList Thinkers[MAX_STATNUM+2]; // Current thinkers
static FThinkerList FreshThinkers[MAX_STATNUM+1]; // Newly created thinkers
static bool bSerialOverride;
friend struct FThinkerList;
friend class FThinkerIterator;
friend class DObject;
friend class FSerializer;
DThinker *NextThinker, *PrevThinker;
};

File diff suppressed because it is too large Load diff

View file

@ -1,358 +0,0 @@
/*
** farchive.h
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#ifndef __FARCHIVE_H__
#define __FARCHIVE_H__
#include <stdio.h>
#include "dobject.h"
#include "r_state.h"
#include "tflags.h"
class FFile
{
public:
enum EOpenMode
{
EReading,
EWriting,
ENotOpen
};
enum ESeekPos
{
ESeekSet,
ESeekRelative,
ESeekEnd
};
virtual ~FFile () {}
virtual bool Open (const char *name, EOpenMode mode) = 0;
virtual void Close () = 0;
virtual void Flush () = 0;
virtual EOpenMode Mode () const = 0;
virtual bool IsPersistent () const = 0;
virtual bool IsOpen () const = 0;
virtual FFile& Write (const void *, unsigned int) = 0;
virtual FFile& Read (void *, unsigned int) = 0;
virtual unsigned int Tell () const = 0;
virtual FFile& Seek (int, ESeekPos) = 0;
inline FFile& Seek (unsigned int i, ESeekPos p) { return Seek ((int)i, p); }
};
class FCompressedFile : public FFile
{
public:
FCompressedFile ();
FCompressedFile (const char *name, EOpenMode mode, bool dontcompress = false);
FCompressedFile (FILE *file, EOpenMode mode, bool dontcompress = false, bool postopen=true);
~FCompressedFile ();
bool Open (const char *name, EOpenMode mode);
void Close ();
void Flush ();
EOpenMode Mode () const;
bool IsPersistent () const { return true; }
bool IsOpen () const;
unsigned int GetSize () const { return m_BufferSize; }
FFile &Write (const void *, unsigned int);
FFile &Read (void *, unsigned int);
unsigned int Tell () const;
FFile &Seek (int, ESeekPos);
protected:
unsigned int m_Pos;
unsigned int m_BufferSize;
unsigned int m_MaxBufferSize;
unsigned char *m_Buffer;
bool m_NoCompress;
EOpenMode m_Mode;
FILE *m_File;
void Implode ();
void Explode ();
virtual bool FreeOnExplode () { return true; }
void PostOpen ();
private:
void BeEmpty ();
};
class FCompressedMemFile : public FCompressedFile
{
public:
FCompressedMemFile ();
FCompressedMemFile (FILE *file); // Create for reading
~FCompressedMemFile ();
bool Open (const char *name, EOpenMode mode); // Works for reading only
bool Open (void *memblock); // Open for reading only
bool Open (); // Open for writing only
bool Reopen (); // Re-opens imploded file for reading only
void Close ();
bool IsOpen () const;
void GetSizes(unsigned int &one, unsigned int &two) const;
void Serialize (FArchive &arc);
protected:
bool FreeOnExplode () { return !m_SourceFromMem; }
private:
bool m_SourceFromMem;
unsigned char *m_ImplodedBuffer;
};
class FPNGChunkFile : public FCompressedFile
{
public:
FPNGChunkFile (FILE *file, DWORD id); // Create for writing
FPNGChunkFile (FILE *file, DWORD id, size_t chunklen); // Create for reading
void Close ();
private:
DWORD m_ChunkID;
};
class FArchive
{
public:
FArchive (FFile &file);
virtual ~FArchive ();
inline bool IsLoading () const { return m_Loading; }
inline bool IsStoring () const { return m_Storing; }
inline bool IsPeristent () const { return m_Persistent; }
void SetHubTravel () { m_HubTravel = true; }
void Close ();
virtual void Write (const void *mem, unsigned int len);
virtual void Read (void *mem, unsigned int len);
void WriteString(const FString &str);
void WriteString (const char *str);
void WriteByte(BYTE val);
void WriteInt16(WORD val);
void WriteInt32(DWORD val);
void WriteInt64(QWORD val);
void WriteCount (DWORD count);
DWORD ReadCount ();
void UserWriteClass (PClass *info);
void UserReadClass (PClass *&info);
template<typename T> void UserReadClass(T *&info)
{
PClass *myclass;
UserReadClass(myclass);
info = dyn_cast<T>(myclass);
}
FArchive& operator<< (BYTE &c);
FArchive& operator<< (WORD &s);
FArchive& operator<< (DWORD &i);
FArchive& operator<< (QWORD &i);
FArchive& operator<< (QWORD_UNION &i) { return operator<< (i.AsOne); }
FArchive& operator<< (float &f);
FArchive& operator<< (double &d);
FArchive& operator<< (char *&str);
FArchive& operator<< (FName &n);
FArchive& operator<< (FString &str);
FArchive& SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize);
FArchive& SerializeObject (DObject *&object, PClass *type);
FArchive& WriteObject (DObject *obj);
FArchive& ReadObject (DObject *&obj, PClass *wanttype);
void WriteName (const char *name);
const char *ReadName (); // The returned name disappears with the archive, unlike strings
void WriteSprite (int spritenum);
int ReadSprite ();
inline FArchive& operator<< (SBYTE &c) { return operator<< ((BYTE &)c); }
inline FArchive& operator<< (SWORD &s) { return operator<< ((WORD &)s); }
inline FArchive& operator<< (SDWORD &i) { return operator<< ((DWORD &)i); }
inline FArchive& operator<< (SQWORD &i) { return operator<< ((QWORD &)i); }
inline FArchive& operator<< (unsigned char *&str) { return operator<< ((char *&)str); }
inline FArchive& operator<< (signed char *&str) { return operator<< ((char *&)str); }
inline FArchive& operator<< (bool &b) { return operator<< ((BYTE &)b); }
inline FArchive& operator<< (DObject* &object) { return ReadObject (object, RUNTIME_CLASS(DObject)); }
void EnableThinkers()
{
m_ThinkersAllowed = true;
}
bool ThinkersAllowed()
{
return m_ThinkersAllowed;
}
protected:
enum { EObjectHashSize = 137 };
DWORD MapObject (DObject *obj);
DWORD WriteClass (PClass *info);
PClass *ReadClass ();
PClass *ReadClass (const PClass *wanttype);
PClass *ReadStoredClass (const PClass *wanttype);
DWORD AddName (const char *name);
DWORD AddName (unsigned int start); // Name has already been added to storage
DWORD FindName (const char *name) const;
DWORD FindName (const char *name, unsigned int bucket) const;
bool m_Persistent; // meant for persistent storage (disk)?
bool m_Loading; // extracting objects?
bool m_Storing; // inserting objects?
bool m_HubTravel; // travelling inside a hub?
FFile *m_File; // unerlying file object
TMap<PClass *, DWORD> ClassToArchive; // Maps PClass to archive type index
TArray<PClass *> ArchiveToClass; // Maps archive type index to PClass
TMap<DObject *, DWORD> ObjectToArchive; // Maps objects to archive index
TArray<DObject *> ArchiveToObject; // Maps archive index to objects
struct NameMap
{
DWORD StringStart; // index into m_NameStorage
DWORD HashNext; // next in hash bucket
enum { NO_INDEX = 0xffffffff };
};
TArray<NameMap> m_Names;
TArray<char> m_NameStorage;
unsigned int m_NameHash[EObjectHashSize];
int *m_SpriteMap;
size_t m_NumSprites;
bool m_ThinkersAllowed = false;
FArchive ();
void AttachToFile (FFile &file);
private:
FArchive (const FArchive &) {}
void operator= (const FArchive &) {}
};
// Create an FPNGChunkFile and FArchive in one step
class FPNGChunkArchive : public FArchive
{
public:
FPNGChunkArchive (FILE *file, DWORD chunkid);
FPNGChunkArchive (FILE *file, DWORD chunkid, size_t chunklen);
~FPNGChunkArchive ();
FPNGChunkFile Chunk;
};
inline FArchive &operator<< (FArchive &arc, PalEntry &p)
{
return arc << p.a << p.r << p.g << p.b;
}
template<class T>
inline FArchive &operator<< (FArchive &arc, T* &object)
{
return arc.SerializeObject ((DObject*&)object, RUNTIME_TEMPLATE_CLASS(T));
}
class FFont;
FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font);
template<> inline FArchive &operator<< <FFont> (FArchive &arc, FFont* &font)
{
return SerializeFFontPtr (arc, font);
}
struct FStrifeDialogueNode;
struct FSwitchDef;
struct FDoorAnimation;
struct FLinePortal;
template<> FArchive &operator<< (FArchive &arc, FStrifeDialogueNode *&node);
template<> FArchive &operator<< (FArchive &arc, FSwitchDef* &sw);
template<> FArchive &operator<< (FArchive &arc, FDoorAnimation* &da);
FArchive &operator<< (FArchive &arc, FLinePortal &da);
FArchive &operator<< (FArchive &arc, FSectorPortal &da);
template<class T,class TT>
inline FArchive &operator<< (FArchive &arc, TArray<T,TT> &self)
{
if (arc.IsStoring())
{
arc.WriteCount(self.Count);
}
else
{
DWORD numStored = arc.ReadCount();
self.Resize(numStored);
}
for (unsigned int i = 0; i < self.Count; ++i)
{
arc << self.Array[i];
}
return arc;
}
struct sector_t;
struct line_t;
struct vertex_t;
struct side_t;
FArchive &operator<< (FArchive &arc, sector_t *&sec);
FArchive &operator<< (FArchive &arc, const sector_t *&sec);
FArchive &operator<< (FArchive &arc, line_t *&line);
FArchive &operator<< (FArchive &arc, vertex_t *&vert);
FArchive &operator<< (FArchive &arc, side_t *&side);
FArchive &operator<<(FArchive &arc, DAngle &ang);
FArchive &operator<<(FArchive &arc, DVector3 &vec);
FArchive &operator<<(FArchive &arc, DVector2 &vec);
template<typename T, typename TT>
FArchive& operator<< (FArchive& arc, TFlags<T, TT>& flag)
{
return flag.Serialize (arc);
}
#endif //__FARCHIVE_H__

View file

@ -600,3 +600,58 @@ char *MemoryArrayReader::Gets(char *strbuf, int len)
{
return GetsFromBuffer((char*)&buf[0], strbuf, len);
}
//==========================================================================
//
// FileWriter (the motivation here is to have a buffer writing subclass)
//
//==========================================================================
bool FileWriter::OpenDirect(const char *filename)
{
File = fopen(filename, "wb");
return (File != NULL);
}
FileWriter *FileWriter::Open(const char *filename)
{
FileWriter *fwrit = new FileWriter();
if (fwrit->OpenDirect(filename))
{
return fwrit;
}
delete fwrit;
return NULL;
}
size_t FileWriter::Write(const void *buffer, size_t len)
{
if (File != NULL)
{
return fwrite(buffer, 1, len, File);
}
else
{
return 0;
}
}
size_t FileWriter::Printf(const char *fmt, ...)
{
va_list ap;
FString out;
va_start(ap, fmt);
out.VFormat(fmt, ap);
va_end(ap);
return Write(out.GetChars(), out.Len());
}
size_t BufferWriter::Write(const void *buffer, size_t len)
{
unsigned int ofs = mBuffer.Reserve((unsigned)len);
memcpy(&mBuffer[ofs], buffer, len);
return len;
}

View file

@ -356,4 +356,46 @@ protected:
};
class FileWriter
{
protected:
bool OpenDirect(const char *filename);
FileWriter()
{
File = NULL;
}
public:
virtual ~FileWriter()
{
if (File != NULL) fclose(File);
}
static FileWriter *Open(const char *filename);
virtual size_t Write(const void *buffer, size_t len);
size_t Printf(const char *fmt, ...);
protected:
FILE *File;
protected:
bool CloseOnDestruct;
};
class BufferWriter : public FileWriter
{
protected:
TArray<unsigned char> mBuffer;
public:
BufferWriter() {}
virtual size_t Write(const void *buffer, size_t len) override;
TArray<unsigned char> *GetBuffer() { return &mBuffer; }
};
#endif

View file

@ -1,204 +0,0 @@
/*
** t_fspic.cpp
** Fragglescript HUD pics (incomplete and untested!)
**
**---------------------------------------------------------------------------
** Copyright 2005 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include "t_script.h"
#include "doomtype.h"
#include "p_local.h"
#include "farchive.h"
#include "sbar.h"
#include "v_video.h"
struct FHudPic
{
FTextureID texturenum;
int xpos;
int ypos;
bool draw;
void Serialize(FArchive & arc)
{
arc << xpos << ypos << draw << texturenum;
}
};
//======================================================================
//
//======================================================================
class DHUDPicManager : public DHUDMessage
{
// This is no real hudmessage but this way I don't need any external code to handle this
// because the hudmessage and thinker code handles everything automatically
DECLARE_CLASS(DHUDPicManager, DHUDMessage)
float basetrans;
public:
TArray<FHudPic> piclist;
DHUDPicManager();
~DHUDPicManager() {}
void Serialize(FArchive & ar);
virtual void DoDraw (int linenum, int x, int y, int hudheight, float translucent);
void DoDraw (int, int, int, bool, int) { assert(false); }
} ;
IMPLEMENT_CLASS(DHUDPicManager)
//======================================================================
//
//======================================================================
DHUDPicManager::DHUDPicManager()
{
HUDWidth=HUDHeight=0;
basetrans=0.8f;
//SetID(0xffffffff);
NumLines=1;
HoldTics=0; // stay forever!
//logtoconsole=false;
}
//======================================================================
//
//======================================================================
void DHUDPicManager::Serialize(FArchive & ar)
{
Super::Serialize(ar);
short count=piclist.Size();
ar << count << basetrans;
if (ar.IsLoading()) piclist.Resize(count);
for(int i=0;i<count;i++) piclist[i].Serialize(ar);
}
//======================================================================
//
//======================================================================
void DHUDPicManager::DoDraw (int linenum, int x, int y, int hudheight, float translucent)
{
for(unsigned int i=0; i<piclist.Size();i++) if (piclist[i].texturenum.isValid() && piclist[i].draw)
{
FTexture * tex = TexMan[piclist[i].texturenum];
if (tex) screen->DrawTexture(tex, piclist[i].xpos, piclist[i].ypos, DTA_320x200, true,
DTA_AlphaF, translucent*basetrans, TAG_DONE);
}
}
//======================================================================
//
//======================================================================
static TArray<FHudPic> & GetPicList()
{
//TThinkerIterator<DHUDPicManager> it;
DHUDPicManager * pm=NULL;//it.Next();
if (!pm) pm=new DHUDPicManager;
return pm->piclist;
}
//======================================================================
//
// External interface
//
//======================================================================
//======================================================================
//
//======================================================================
int HU_GetFSPic(FTextureID texturenum, int xpos, int ypos)
{
TArray<FHudPic> &piclist=GetPicList();
unsigned int i;
for(i=0;i<piclist.Size();i++) if (piclist[i].texturenum.isValid()) continue;
if (i==piclist.Size()) i=piclist.Reserve(1);
FHudPic * pic=&piclist[i];
piclist[i].texturenum = texturenum;
piclist[i].xpos = xpos;
piclist[i].ypos = ypos;
piclist[i].draw = false;
return i;
}
//======================================================================
//
//======================================================================
int HU_DeleteFSPic(unsigned handle)
{
TArray<FHudPic> &piclist=GetPicList();
if(handle >= piclist.Size()) return -1;
piclist[handle].texturenum.SetInvalid();
return 0;
}
//======================================================================
//
//======================================================================
int HU_ModifyFSPic(unsigned handle, FTextureID texturenum, int xpos, int ypos)
{
TArray<FHudPic> &piclist=GetPicList();
if(handle >= piclist.Size()) return -1;
if(!piclist[handle].texturenum.isValid()) return -1;
piclist[handle].texturenum = texturenum;
piclist[handle].xpos = xpos;
piclist[handle].ypos = ypos;
return 0;
}
//======================================================================
//
//======================================================================
int HU_FSDisplay(unsigned handle, bool newval)
{
TArray<FHudPic> &piclist=GetPicList();
if(handle >= piclist.Size()) return -1;
if(!piclist[handle].texturenum.isValid()) return -1;
piclist[handle].draw = newval;
return 0;
}

View file

@ -65,7 +65,7 @@
#include "v_palette.h"
#include "v_font.h"
#include "r_data/colormaps.h"
#include "farchive.h"
#include "serializer.h"
#include "p_setup.h"
#include "p_spec.h"
#include "r_utility.h"
@ -1780,7 +1780,7 @@ class DLightLevel : public DLighting
public:
DLightLevel(sector_t * s,int destlevel,int speed);
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
void Destroy() { Super::Destroy(); m_Sector->lightingdata=NULL; }
};
@ -1789,11 +1789,11 @@ public:
IMPLEMENT_CLASS (DLightLevel)
void DLightLevel::Serialize (FArchive &arc)
void DLightLevel::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << destlevel << speed;
if (arc.IsLoading()) m_Sector->lightingdata=this;
arc("destlevel", destlevel)
("speed", speed);
}
@ -3647,58 +3647,24 @@ void FParser::SF_Pow()
//==========================================================================
int HU_GetFSPic(FTextureID lumpnum, int xpos, int ypos);
int HU_DeleteFSPic(unsigned int handle);
int HU_ModifyFSPic(unsigned int handle, FTextureID lumpnum, int xpos, int ypos);
int HU_FSDisplay(unsigned int handle, bool newval);
void FParser::SF_NewHUPic()
{
if (CheckArgs(3))
{
t_return.type = svt_int;
t_return.value.i = HU_GetFSPic(
TexMan.GetTexture(stringvalue(t_argv[0]), FTexture::TEX_MiscPatch, FTextureManager::TEXMAN_TryAny),
intvalue(t_argv[1]), intvalue(t_argv[2]));
}
// disabled because it was never used and never tested
}
void FParser::SF_DeleteHUPic()
{
if (CheckArgs(1))
{
if (HU_DeleteFSPic(intvalue(t_argv[0])) == -1)
script_error("deletehupic: Invalid sfpic handle: %i\n", intvalue(t_argv[0]));
}
// disabled because it was never used and never tested
}
void FParser::SF_ModifyHUPic()
{
if (t_argc != 4)
{
script_error("modifyhupic: invalid number of arguments\n");
return;
}
if (HU_ModifyFSPic(intvalue(t_argv[0]),
TexMan.GetTexture(stringvalue(t_argv[0]), FTexture::TEX_MiscPatch, FTextureManager::TEXMAN_TryAny),
intvalue(t_argv[2]), intvalue(t_argv[3])) == -1)
{
script_error("modifyhypic: invalid sfpic handle %i\n", intvalue(t_argv[0]));
}
return;
// disabled because it was never used and never tested
}
void FParser::SF_SetHUPicDisplay()
{
if (t_argc != 2)
{
script_error("sethupicdisplay: invalud number of arguments\n");
return;
}
if (HU_FSDisplay(intvalue(t_argv[0]), intvalue(t_argv[1]) > 0 ? 1 : 0) == -1)
script_error("sethupicdisplay: invalid pic handle %i\n", intvalue(t_argv[0]));
// disabled because it was never used and never tested
}

View file

@ -56,7 +56,7 @@
#include "t_script.h"
#include "i_system.h"
#include "w_wad.h"
#include "farchive.h"
#include "serializer.h"
//==========================================================================
@ -81,10 +81,14 @@ END_POINTERS
//
//==========================================================================
void DFsSection::Serialize(FArchive &ar)
void DFsSection::Serialize(FSerializer &arc)
{
Super::Serialize(ar);
ar << type << start_index << end_index << loop_index << next;
Super::Serialize(arc);
arc("type", type)
("start_index", start_index)
("end_index", end_index)
("loop_index", loop_index)
("next", next);
}
//==========================================================================

View file

@ -54,7 +54,7 @@
#include "i_system.h"
#include "doomerrors.h"
#include "doomstat.h"
#include "farchive.h"
#include "serializer.h"
//==========================================================================
//
@ -162,6 +162,19 @@ DFsScript::DFsScript()
lastiftrue = false;
}
//==========================================================================
//
// This is here to delete the locally allocated buffer in case this
// gets forcibly destroyed
//
//==========================================================================
DFsScript::~DFsScript()
{
if (data != NULL) delete[] data;
data = NULL;
}
//==========================================================================
//
//
@ -187,18 +200,23 @@ void DFsScript::Destroy()
//
//==========================================================================
void DFsScript::Serialize(FArchive &arc)
void DFsScript::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
// don't save a reference to the global script
if (parent == global_script) parent = NULL;
if (parent == global_script) parent = nullptr;
arc << data << scriptnum << len << parent << trigger << lastiftrue;
for(int i=0; i< SECTIONSLOTS; i++) arc << sections[i];
for(int i=0; i< VARIABLESLOTS; i++) arc << variables[i];
for(int i=0; i< MAXSCRIPTS; i++) arc << children[i];
arc("data", data)
("scriptnum", scriptnum)
("len", len)
("parent", parent)
("trigger", trigger)
("lastiftrue", lastiftrue)
.Array("sections", sections, SECTIONSLOTS)
.Array("variables", variables, VARIABLESLOTS)
.Array("children", children, MAXSCRIPTS);
if (parent == NULL) parent = global_script;
if (parent == nullptr) parent = global_script;
}
//==========================================================================
@ -338,12 +356,17 @@ void DRunningScript::Destroy()
//
//==========================================================================
void DRunningScript::Serialize(FArchive &arc)
void DRunningScript::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc << script << save_point << wait_type << wait_data << prev << next << trigger;
for(int i=0; i< VARIABLESLOTS; i++) arc << variables[i];
arc("script", script)
("save_point", save_point)
("wait_type", wait_type)
("wait_data", wait_data)
("prev", prev)
("next", next)
("trigger", trigger)
.Array("variables", variables, VARIABLESLOTS);
}
@ -416,10 +439,13 @@ void DFraggleThinker::Destroy()
//
//==========================================================================
void DFraggleThinker::Serialize(FArchive &arc)
void DFraggleThinker::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc << LevelScript << RunningScripts << SpawnedThings << nocheckposition;
arc("levelscript", LevelScript)
("runningscripts", RunningScripts)
("spawnedthings", SpawnedThings)
("nocheckposition", nocheckposition);
}
//==========================================================================

View file

@ -189,7 +189,7 @@ public:
void GetValue(svalue_t &result);
void SetValue(const svalue_t &newvalue);
void Serialize(FArchive &ar);
void Serialize(FSerializer &ar);
};
//==========================================================================
@ -238,7 +238,7 @@ public:
next = NULL;
}
void Serialize(FArchive &ar);
void Serialize(FSerializer &ar);
};
@ -336,8 +336,9 @@ public:
// true or false
DFsScript();
~DFsScript();
void Destroy();
void Serialize(FArchive &ar);
void Serialize(FSerializer &ar);
DFsVariable *NewVariable(const char *name, int vtype);
void NewFunction(const char *name, void (FParser::*handler)());
@ -652,7 +653,7 @@ class DRunningScript : public DObject
public:
DRunningScript(AActor *trigger=NULL, DFsScript *owner = NULL, int index = 0) ;
void Destroy();
void Serialize(FArchive &arc);
void Serialize(FSerializer &arc);
TObjPtr<DFsScript> script;
@ -689,7 +690,7 @@ public:
void Destroy();
void Serialize(FArchive & arc);
void Serialize(FSerializer & arc);
void Tick();
size_t PropagateMark();
size_t PointerSubstitution (DObject *old, DObject *notOld);

View file

@ -54,7 +54,7 @@
#include "t_script.h"
#include "a_pickups.h"
#include "farchive.h"
#include "serializer.h"
//==========================================================================
@ -306,10 +306,15 @@ void DFsVariable::SetValue(const svalue_t &newvalue)
//
//==========================================================================
void DFsVariable::Serialize(FArchive & ar)
void DFsVariable::Serialize(FSerializer & ar)
{
Super::Serialize(ar);
ar << Name << type << string << actor << value.i << next;
ar("name", Name)
("type", type)
("string", string)
("actor", actor)
("value", value.i)
("next", next);
}

View file

@ -120,7 +120,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit)
bool isdefault = false;
// shoot a cube at current target
targ = state->GetNextInList(PClass::FindClass("BossTarget"), G_SkillProperty(SKILLP_EasyBossBrain));
targ = state->GetNextInList(PClass::FindActor("BossTarget"), G_SkillProperty(SKILLP_EasyBossBrain));
if (targ != NULL)
{

View file

@ -29,7 +29,8 @@ public:
void Tick ();
void SetWeapon (EMarineWeapon);
void SetSprite (PClassActor *source);
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
int CurrentWeapon;

View file

@ -14,10 +14,10 @@
#include "a_specialspot.h"
#include "templates.h"
#include "m_bbox.h"
#include "farchive.h"
#include "portal.h"
#include "d_player.h"
#include "p_maputl.h"
#include "serializer.h"
#include "g_shared/a_pickups.h"
// Include all the other Doom stuff here to reduce compile time

View file

@ -21,19 +21,14 @@ static FRandom pr_m_fireshotgun2 ("SMarineFireSSG");
IMPLEMENT_CLASS (AScriptedMarine)
void AScriptedMarine::Serialize (FArchive &arc)
void AScriptedMarine::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
if (arc.IsStoring ())
{
arc.WriteSprite (SpriteOverride);
}
else
{
SpriteOverride = arc.ReadSprite ();
}
arc << CurrentWeapon;
auto def = (AScriptedMarine*)GetDefault();
arc.Sprite("spriteoverride", SpriteOverride, &def->SpriteOverride)
("currentweapon", CurrentWeapon, def->CurrentWeapon);
}
void AScriptedMarine::Activate (AActor *activator)

View file

@ -27,6 +27,7 @@
#include <stdio.h>
#include <stddef.h>
#include <time.h>
#include <memory>
#ifdef __APPLE__
#include <CoreServices/CoreServices.h>
#endif
@ -78,12 +79,14 @@
#include "p_acs.h"
#include "p_effect.h"
#include "m_joy.h"
#include "farchive.h"
#include "r_renderer.h"
#include "r_utility.h"
#include "a_morph.h"
#include "p_spec.h"
#include "r_data/colormaps.h"
#include "serializer.h"
#include "w_zip.h"
#include "resourcefiles/resourcefile.h"
#include <zlib.h>
@ -110,10 +113,11 @@ void G_DoWorldDone (void);
void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description);
void G_DoAutoSave ();
void STAT_Write(FILE *file);
void STAT_Read(PNGHandle *png);
void STAT_Serialize(FSerializer &file);
bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompressedBuffer> &content);
FIntCVar gameskill ("skill", 2, CVAR_SERVERINFO|CVAR_LATCH);
CVAR(Bool, save_formatted, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // use formatted JSON for saves (more readable but a larger files and a bit slower.
CVAR (Int, deathmatch, 0, CVAR_SERVERINFO|CVAR_LATCH);
CVAR (Bool, chasedemo, false, 0);
CVAR (Bool, storesavepic, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -1775,7 +1779,7 @@ void G_LoadGame (const char* name, bool hidecon)
}
}
static bool CheckSingleWad (char *name, bool &printRequires, bool printwarn)
static bool CheckSingleWad (const char *name, bool &printRequires, bool printwarn)
{
if (name == NULL)
{
@ -1795,22 +1799,20 @@ static bool CheckSingleWad (char *name, bool &printRequires, bool printwarn)
}
}
printRequires = true;
delete[] name;
return false;
}
delete[] name;
return true;
}
// Return false if not all the needed wads have been loaded.
bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn)
bool G_CheckSaveGameWads (FSerializer &arc, bool printwarn)
{
char *text;
bool printRequires = false;
FString text;
text = M_GetPNGText (png, "Game WAD");
arc("Game WAD", text);
CheckSingleWad (text, printRequires, printwarn);
text = M_GetPNGText (png, "Map WAD");
arc("Map WAD", text);
CheckSingleWad (text, printRequires, printwarn);
if (printRequires)
@ -1828,9 +1830,6 @@ bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn)
void G_DoLoadGame ()
{
char sigcheck[20];
char *text = NULL;
char *map;
bool hidecon;
if (gameaction != ga_autoloadgame)
@ -1840,151 +1839,168 @@ void G_DoLoadGame ()
hidecon = gameaction == ga_loadgamehidecon;
gameaction = ga_nothing;
FILE *stdfile = fopen (savename.GetChars(), "rb");
if (stdfile == NULL)
FResourceFile *resfile = FResourceFile::OpenResourceFile(savename.GetChars(), nullptr, true, true);
if (resfile == nullptr)
{
Printf ("Could not read savegame '%s'\n", savename.GetChars());
return;
}
PNGHandle *png = M_VerifyPNG (stdfile);
if (png == NULL)
try
{
fclose (stdfile);
Printf ("'%s' is not a valid (PNG) savegame\n", savename.GetChars());
return;
}
SaveVersion = 0;
// Check whether this savegame actually has been created by a compatible engine.
// Since there are ZDoom derivates using the exact same savegame format but
// with mutual incompatibilities this check simplifies things significantly.
char *engine = M_GetPNGText (png, "Engine");
if (engine == NULL || 0 != strcmp (engine, GAMESIG))
{
// Make a special case for the message printed for old savegames that don't
// have this information.
if (engine == NULL)
FResourceLump *info = resfile->FindLump("info.json");
if (info == nullptr)
{
Printf ("Savegame is from an incompatible version\n");
delete resfile;
Printf("'%s' is not a valid savegame: Missing 'info.json'.\n", savename.GetChars());
return;
}
else
SaveVersion = 0;
void *data = info->CacheLump();
FSerializer arc;
if (!arc.OpenReader((const char *)data, info->LumpSize))
{
Printf ("Savegame is from another ZDoom-based engine: %s\n", engine);
delete[] engine;
Printf("Failed to access savegame info\n");
delete resfile;
return;
}
delete png;
fclose (stdfile);
return;
}
if (engine != NULL)
{
delete[] engine;
}
SaveVersion = 0;
if (!M_GetPNGText (png, "ZDoom Save Version", sigcheck, 20) ||
0 != strncmp (sigcheck, SAVESIG, 9) || // ZDOOMSAVE is the first 9 chars
(SaveVersion = atoi (sigcheck+9)) < MINSAVEVER)
{
delete png;
fclose (stdfile);
Printf ("Savegame is from an incompatible version");
if (SaveVersion != 0)
// Check whether this savegame actually has been created by a compatible engine.
// Since there are ZDoom derivates using the exact same savegame format but
// with mutual incompatibilities this check simplifies things significantly.
FString savever, engine, map;
arc("Save Version", SaveVersion);
arc("Engine", engine);
arc("Current Map", map);
if (engine.CompareNoCase(GAMESIG) != 0)
{
Printf(": %d (%d is the oldest supported)", SaveVersion, MINSAVEVER);
// Make a special case for the message printed for old savegames that don't
// have this information.
if (engine.IsEmpty())
{
Printf("Savegame is from an incompatible version\n");
}
else
{
Printf("Savegame is from another ZDoom-based engine: %s\n", engine);
}
delete resfile;
return;
}
Printf("\n");
if (SaveVersion < MINSAVEVER || SaveVersion > SAVEVER)
{
delete resfile;
Printf("Savegame is from an incompatible version");
if (SaveVersion < MINSAVEVER)
{
Printf(": %d (%d is the oldest supported)", SaveVersion, MINSAVEVER);
}
else
{
Printf(": %d (%d is the highest supported)", SaveVersion, SAVEVER);
}
Printf("\n");
return;
}
if (!G_CheckSaveGameWads(arc, true))
{
delete resfile;
return;
}
if (map.IsEmpty())
{
Printf("Savegame is missing the current map\n");
delete resfile;
return;
}
// Now that it looks like we can load this save, hide the fullscreen console if it was up
// when the game was selected from the menu.
if (hidecon && gamestate == GS_FULLCONSOLE)
{
gamestate = GS_HIDECONSOLE;
}
// we are done with info.json.
arc.Close();
info = resfile->FindLump("globals.json");
if (info == nullptr)
{
delete resfile;
Printf("'%s' is not a valid savegame: Missing 'globals.json'.\n", savename.GetChars());
return;
}
data = info->CacheLump();
if (!arc.OpenReader((const char *)data, info->LumpSize))
{
Printf("Failed to access savegame info\n");
delete resfile;
return;
}
// Read intermission data for hubs
G_SerializeHub(arc);
bglobal.RemoveAllBots(true);
FString cvar;
arc("importantcvars", cvar);
if (!cvar.IsEmpty())
{
BYTE *vars_p = (BYTE *)cvar.GetChars();
C_ReadCVars(&vars_p);
}
DWORD time[2] = { 1,0 };
arc("ticrate", time[0])
("leveltime", time[1]);
// dearchive all the modifications
level.time = Scale(time[1], TICRATE, time[0]);
G_ReadSnapshots(resfile);
delete resfile; // we no longer need the resource file below this point
resfile = nullptr;
G_ReadVisited(arc);
// load a base level
savegamerestore = true; // Use the player actors in the savegame
bool demoplaybacksave = demoplayback;
G_InitNew(map, false);
demoplayback = demoplaybacksave;
savegamerestore = false;
STAT_Serialize(arc);
FRandom::StaticReadRNGState(arc);
P_ReadACSDefereds(arc);
P_ReadACSVars(arc);
NextSkill = -1;
arc("nextskill", NextSkill);
if (level.info != nullptr)
level.info->Snapshot.Clean();
BackupSaveName = savename;
// At this point, the GC threshold is likely a lot higher than the
// amount of memory in use, so bring it down now by starting a
// collection.
GC::StartCollection();
}
catch (...)
{
// delete the resource file if anything goes wrong in here.
if (resfile != nullptr) delete resfile;
return;
}
if (!G_CheckSaveGameWads (png, true))
{
fclose (stdfile);
return;
}
map = M_GetPNGText (png, "Current Map");
if (map == NULL)
{
Printf ("Savegame is missing the current map\n");
fclose (stdfile);
return;
}
// Now that it looks like we can load this save, hide the fullscreen console if it was up
// when the game was selected from the menu.
if (hidecon && gamestate == GS_FULLCONSOLE)
{
gamestate = GS_HIDECONSOLE;
}
// Read intermission data for hubs
G_ReadHubInfo(png);
bglobal.RemoveAllBots (true);
text = M_GetPNGText (png, "Important CVARs");
if (text != NULL)
{
BYTE *vars_p = (BYTE *)text;
C_ReadCVars (&vars_p);
delete[] text;
}
// dearchive all the modifications
if (M_FindPNGChunk (png, MAKE_ID('p','t','I','c')) == 8)
{
DWORD time[2];
fread (&time, 8, 1, stdfile);
time[0] = BigLong((unsigned int)time[0]);
time[1] = BigLong((unsigned int)time[1]);
level.time = Scale (time[1], TICRATE, time[0]);
}
else
{ // No ptIc chunk so we don't know how long the user was playing
level.time = 0;
}
G_ReadSnapshots (png);
// load a base level
savegamerestore = true; // Use the player actors in the savegame
bool demoplaybacksave = demoplayback;
G_InitNew (map, false);
demoplayback = demoplaybacksave;
delete[] map;
savegamerestore = false;
STAT_Read(png);
FRandom::StaticReadRNGState(png);
P_ReadACSDefereds(png);
P_ReadACSVars(png);
NextSkill = -1;
if (M_FindPNGChunk (png, MAKE_ID('s','n','X','t')) == 1)
{
BYTE next;
fread (&next, 1, 1, stdfile);
NextSkill = next;
}
if (level.info->snapshot != NULL)
{
delete level.info->snapshot;
level.info->snapshot = NULL;
}
BackupSaveName = savename;
delete png;
fclose (stdfile);
// At this point, the GC threshold is likely a lot higher than the
// amount of memory in use, so bring it down now by starting a
// collection.
GC::StartCollection();
}
@ -2047,7 +2063,7 @@ FString G_BuildSaveName (const char *prefix, int slot)
name << prefix;
if (slot >= 0)
{
name.AppendFormat("%d.zds", slot);
name.AppendFormat("%d." SAVEGAME_EXT, slot);
}
return name;
}
@ -2104,23 +2120,23 @@ void G_DoAutoSave ()
}
static void PutSaveWads (FILE *file)
static void PutSaveWads (FSerializer &arc)
{
const char *name;
// Name of IWAD
name = Wads.GetWadName (FWadCollection::IWAD_FILENUM);
M_AppendPNGText (file, "Game WAD", name);
arc.AddString("Game WAD", name);
// Name of wad the map resides in
if (Wads.GetLumpFile (level.lumpnum) > 1)
{
name = Wads.GetWadName (Wads.GetLumpFile (level.lumpnum));
M_AppendPNGText (file, "Map WAD", name);
arc.AddString("Map WAD", name);
}
}
static void PutSaveComment (FILE *file)
static void PutSaveComment (FSerializer &arc)
{
char comment[256];
const char *readableTime;
@ -2135,7 +2151,7 @@ static void PutSaveComment (FILE *file)
strncpy (comment+15, readableTime+10, 9);
comment[24] = 0;
M_AppendPNGText (file, "Creation Time", comment);
arc.AddString("Creation Time", comment);
// Get level name
//strcpy (comment, level.level_name);
@ -2150,10 +2166,10 @@ static void PutSaveComment (FILE *file)
comment[len+16] = 0;
// Write out the comment
M_AppendPNGText (file, "Comment", comment);
arc.AddString("Comment", comment);
}
static void PutSavePic (FILE *file, int width, int height)
static void PutSavePic (FileWriter *file, int width, int height)
{
if (width <= 0 || height <= 0 || !storesavepic)
{
@ -2167,6 +2183,9 @@ static void PutSavePic (FILE *file, int width, int height)
void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description)
{
TArray<FCompressedBuffer> savegame_content;
TArray<FString> savegame_filenames;
char buf[100];
// Do not even try, if we're not in a level. (Can happen after
@ -2178,7 +2197,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
if (demoplayback)
{
filename = G_BuildSaveName ("demosave.zds", -1);
filename = G_BuildSaveName ("demosave." SAVEGAME_EXT, -1);
}
if (cl_waitforsave)
@ -2187,87 +2206,97 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
insave = true;
G_SnapshotLevel ();
FILE *stdfile = fopen (filename, "wb");
BufferWriter savepic;
FSerializer savegameinfo; // this is for displayable info about the savegame
FSerializer savegameglobals; // and this for non-level related info that must be saved.
if (stdfile == NULL)
{
Printf ("Could not create savegame '%s'\n", filename.GetChars());
insave = false;
I_FreezeTime(false);
return;
}
savegameinfo.OpenWriter(true);
savegameglobals.OpenWriter(save_formatted);
SaveVersion = SAVEVER;
PutSavePic (stdfile, SAVEPICWIDTH, SAVEPICHEIGHT);
PutSavePic(&savepic, SAVEPICWIDTH, SAVEPICHEIGHT);
mysnprintf(buf, countof(buf), GAMENAME " %s", GetVersionString());
M_AppendPNGText (stdfile, "Software", buf);
M_AppendPNGText (stdfile, "Engine", GAMESIG);
M_AppendPNGText (stdfile, "ZDoom Save Version", SAVESIG);
M_AppendPNGText (stdfile, "Title", description);
M_AppendPNGText (stdfile, "Current Map", level.MapName);
PutSaveWads (stdfile);
PutSaveComment (stdfile);
// put some basic info into the PNG so that this isn't lost when the image gets extracted.
M_AppendPNGText(&savepic, "Software", buf);
M_AppendPNGText(&savepic, "Title", description);
M_AppendPNGText(&savepic, "Current Map", level.MapName);
M_FinishPNG(&savepic);
int ver = SAVEVER;
savegameinfo.AddString("Software", buf)
.AddString("Engine", GAMESIG)
("Save Version", ver)
.AddString("Title", description)
.AddString("Current Map", level.MapName);
PutSaveWads (savegameinfo);
PutSaveComment (savegameinfo);
// Intermission stats for hubs
G_WriteHubInfo(stdfile);
G_SerializeHub(savegameglobals);
{
FString vars = C_GetMassCVarString(CVAR_SERVERINFO);
M_AppendPNGText (stdfile, "Important CVARs", vars.GetChars());
savegameglobals.AddString("importantcvars", vars.GetChars());
}
if (level.time != 0 || level.maptime != 0)
{
DWORD time[2] = { DWORD(BigLong(TICRATE)), DWORD(BigLong(level.time)) };
M_AppendPNGChunk (stdfile, MAKE_ID('p','t','I','c'), (BYTE *)&time, 8);
int tic = TICRATE;
savegameglobals("ticrate", tic);
savegameglobals("leveltime", level.time);
}
G_WriteSnapshots (stdfile);
STAT_Write(stdfile);
FRandom::StaticWriteRNGState (stdfile);
P_WriteACSDefereds (stdfile);
STAT_Serialize(savegameglobals);
FRandom::StaticWriteRNGState(savegameglobals);
P_WriteACSDefereds(savegameglobals);
P_WriteACSVars(savegameglobals);
G_WriteVisited(savegameglobals);
P_WriteACSVars(stdfile);
if (NextSkill != -1)
{
BYTE next = NextSkill;
M_AppendPNGChunk (stdfile, MAKE_ID('s','n','X','t'), &next, 1);
savegameglobals("nextskill", NextSkill);
}
M_FinishPNG (stdfile);
fclose (stdfile);
auto picdata = savepic.GetBuffer();
FCompressedBuffer bufpng = { picdata->Size(), picdata->Size(), METHOD_STORED, 0, crc32(0, &(*picdata)[0], picdata->Size()), (char*)&(*picdata)[0] };
savegame_content.Push(bufpng);
savegame_filenames.Push("savepic.png");
savegame_content.Push(savegameinfo.GetCompressedOutput());
savegame_filenames.Push("info.json");
savegame_content.Push(savegameglobals.GetCompressedOutput());
savegame_filenames.Push("globals.json");
G_WriteSnapshots (savegame_filenames, savegame_content);
WriteZip(filename, savegame_filenames, savegame_content);
M_NotifyNewSave (filename.GetChars(), description, okForQuicksave);
// Check whether the file is ok.
bool success = false;
stdfile = fopen (filename.GetChars(), "rb");
if (stdfile != NULL)
{
PNGHandle *pngh = M_VerifyPNG(stdfile);
if (pngh != NULL)
{
success = true;
delete pngh;
}
fclose(stdfile);
}
if (success)
// delete the JSON buffers we created just above. Everything else will
// either still be needed or taken care of automatically.
savegame_content[1].Clean();
savegame_content[2].Clean();
// Check whether the file is ok by trying to open it.
FResourceFile *test = FResourceFile::OpenResourceFile(filename, nullptr, true);
if (test != nullptr)
{
delete test;
if (longsavemessages) Printf ("%s (%s)\n", GStrings("GGSAVED"), filename.GetChars());
else Printf ("%s\n", GStrings("GGSAVED"));
}
else Printf(PRINT_HIGH, "Save failed\n");
BackupSaveName = filename;
// We don't need the snapshot any longer.
if (level.info->snapshot != NULL)
{
delete level.info->snapshot;
level.info->snapshot = NULL;
}
level.info->Snapshot.Clean();
insave = false;
I_FreezeTime(false);

View file

@ -24,7 +24,6 @@
#define __G_GAME__
struct event_t;
struct PNGHandle;
//
@ -68,8 +67,8 @@ void G_ScreenShot (char *filename);
FString G_BuildSaveName (const char *prefix, int slot);
struct PNGHandle;
bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn);
class FSerializer;
bool G_CheckSaveGameWads (FSerializer &arc, bool printwarn);
enum EFinishLevelType
{

View file

@ -148,7 +148,7 @@ void P_DSparilTeleport (AActor *actor)
DSpotState *state = DSpotState::GetSpotState();
if (state == NULL) return;
spot = state->GetSpotWithMinMaxDistance(PClass::FindClass("BossSpot"), actor->X(), actor->Y(), 128, 0);
spot = state->GetSpotWithMinMaxDistance(PClass::FindActor("BossSpot"), actor->X(), actor->Y(), 128, 0);
if (spot == NULL) return;
prev = actor->Pos();

View file

@ -14,10 +14,10 @@
#include "templates.h"
#include "r_data/r_translate.h"
#include "doomstat.h"
#include "farchive.h"
#include "d_player.h"
#include "a_morph.h"
#include "p_spec.h"
#include "serializer.h"
// Include all the other Heretic stuff here to reduce compile time
#include "a_chicken.cpp"

View file

@ -866,16 +866,18 @@ class ARainTracker : public AInventory
{
DECLARE_CLASS (ARainTracker, AInventory)
public:
void Serialize (FArchive &arc);
AActor *Rain1, *Rain2;
void Serialize(FSerializer &arc);
TObjPtr<AActor> Rain1, Rain2;
};
IMPLEMENT_CLASS (ARainTracker)
void ARainTracker::Serialize (FArchive &arc)
void ARainTracker::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << Rain1 << Rain2;
arc("rain1", Rain1)
("rain2", Rain2);
}
//----------------------------------------------------------------------------
@ -1140,10 +1142,11 @@ class APhoenixRod : public AWeapon
{
DECLARE_CLASS (APhoenixRod, AWeapon)
public:
void Serialize (FArchive &arc)
void Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << FlameCount;
arc("flamecount", FlameCount);
}
int FlameCount; // for flamethrower duration
};

View file

@ -31,10 +31,11 @@ class ACWeapWraithverge : public AClericWeapon
{
DECLARE_CLASS (ACWeapWraithverge, AClericWeapon)
public:
void Serialize (FArchive &arc)
void Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << CHolyCount;
arc("cholycount", CHolyCount);
}
PalEntry GetBlend ()
{

View file

@ -64,19 +64,21 @@ class AHeresiarch : public AActor
{
DECLARE_CLASS (AHeresiarch, AActor)
public:
const PClass *StopBall;
PClassActor *StopBall;
DAngle BallAngle;
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Die (AActor *source, AActor *inflictor, int dmgflags);
};
IMPLEMENT_CLASS (AHeresiarch)
void AHeresiarch::Serialize (FArchive &arc)
void AHeresiarch::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << StopBall << BallAngle;
arc("stopball", StopBall)
("ballangle", BallAngle);
}
void AHeresiarch::Die (AActor *source, AActor *inflictor, int dmgflags)
@ -105,10 +107,13 @@ public:
DAngle AngleOffset;
DAngle OldAngle;
void Serialize (FArchive &arc)
void Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << AngleOffset << OldAngle;
arc("angleoffset", AngleOffset)
("oldangle", OldAngle);
}
bool SpecialBlastHandling (AActor *source, double strength)

View file

@ -17,13 +17,13 @@
#include "p_terrain.h"
#include "m_bbox.h"
#include "ravenshared.h"
#include "farchive.h"
#include "v_palette.h"
#include "g_game.h"
#include "p_blockmap.h"
#include "r_utility.h"
#include "p_maputl.h"
#include "p_spec.h"
#include "serializer.h"
// Include all the Hexen stuff here to reduce compile time
#include "a_bats.cpp"

View file

@ -29,10 +29,11 @@ class AMWeapBloodscourge : public AMageWeapon
{
DECLARE_CLASS (AMWeapBloodscourge, AMageWeapon)
public:
void Serialize (FArchive &arc)
void Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << MStaffCount;
arc("mstaffcount", MStaffCount);
}
PalEntry GetBlend ()
{

View file

@ -22,7 +22,8 @@ class AThrustFloor : public AActor
DECLARE_CLASS (AThrustFloor, AActor)
HAS_OBJECT_POINTERS
public:
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Activate (AActor *activator);
void Deactivate (AActor *activator);
@ -34,10 +35,10 @@ IMPLEMENT_POINTY_CLASS (AThrustFloor)
DECLARE_POINTER (DirtClump)
END_POINTERS
void AThrustFloor::Serialize (FArchive &arc)
void AThrustFloor::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << DirtClump;
arc("dirtclump", DirtClump);
}
void AThrustFloor::Activate (AActor *activator)

View file

@ -43,7 +43,7 @@
#include "m_png.h"
#include "gstrings.h"
#include "wi_stuff.h"
#include "farchive.h"
#include "serializer.h"
//==========================================================================
@ -54,7 +54,7 @@
struct FHubInfo
{
int finished_ep;
int levelnum;
int maxkills;
int maxitems;
@ -65,7 +65,7 @@ struct FHubInfo
FHubInfo &operator=(const wbstartstruct_t &wbs)
{
finished_ep = wbs.finished_ep;
levelnum = wbs.finished_ep;
maxkills = wbs.maxkills;
maxsecret= wbs.maxsecret;
maxitems = wbs.maxitems;
@ -80,54 +80,54 @@ static TArray<FHubInfo> hubdata;
void G_LeavingHub(int mode, cluster_info_t * cluster, wbstartstruct_t * wbs)
{
unsigned int i,j;
unsigned int i, j;
if (cluster->flags & CLUSTER_HUB)
{
for(i=0;i<hubdata.Size();i++)
for (i = 0; i < hubdata.Size(); i++)
{
if (hubdata[i].finished_ep==level.levelnum)
if (hubdata[i].levelnum == level.levelnum)
{
hubdata[i]=*wbs;
hubdata[i] = *wbs;
break;
}
}
if (i==hubdata.Size())
if (i == hubdata.Size())
{
hubdata[hubdata.Reserve(1)] = *wbs;
}
hubdata[i].finished_ep=level.levelnum;
hubdata[i].levelnum = level.levelnum;
if (!multiplayer && !deathmatch)
{
// The player counters don't work in hubs
hubdata[i].plyr[0].skills=level.killed_monsters;
hubdata[i].plyr[0].sitems=level.found_items;
hubdata[i].plyr[0].ssecret=level.found_secrets;
hubdata[i].plyr[0].skills = level.killed_monsters;
hubdata[i].plyr[0].sitems = level.found_items;
hubdata[i].plyr[0].ssecret = level.found_secrets;
}
if (mode!=FINISH_SameHub)
if (mode != FINISH_SameHub)
{
wbs->maxkills=wbs->maxitems=wbs->maxsecret=0;
for(i=0;i<MAXPLAYERS;i++)
wbs->maxkills = wbs->maxitems = wbs->maxsecret = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
wbs->plyr[i].sitems=wbs->plyr[i].skills=wbs->plyr[i].ssecret=0;
wbs->plyr[i].sitems = wbs->plyr[i].skills = wbs->plyr[i].ssecret = 0;
}
for(i=0;i<hubdata.Size();i++)
for (i = 0; i < hubdata.Size(); i++)
{
wbs->maxkills += hubdata[i].maxkills;
wbs->maxitems += hubdata[i].maxitems;
wbs->maxsecret += hubdata[i].maxsecret;
for(j=0;j<MAXPLAYERS;j++)
for (j = 0; j < MAXPLAYERS; j++)
{
wbs->plyr[j].sitems += hubdata[i].plyr[j].sitems;
wbs->plyr[j].skills += hubdata[i].plyr[j].skills;
wbs->plyr[j].ssecret += hubdata[i].plyr[j].ssecret;
}
}
if (cluster->ClusterName.IsNotEmpty())
if (cluster->ClusterName.IsNotEmpty())
{
if (cluster->flags & CLUSTER_LOOKUPNAME)
{
@ -140,7 +140,7 @@ void G_LeavingHub(int mode, cluster_info_t * cluster, wbstartstruct_t * wbs)
}
}
}
if (mode!=FINISH_SameHub) hubdata.Clear();
if (mode != FINISH_SameHub) hubdata.Clear();
}
//==========================================================================
@ -148,39 +148,41 @@ void G_LeavingHub(int mode, cluster_info_t * cluster, wbstartstruct_t * wbs)
// Serialize intermission info for hubs
//
//==========================================================================
#define HUBS_ID MAKE_ID('h','u','B','s')
static void G_SerializeHub(FArchive & arc)
FSerializer &Serialize(FSerializer &arc, const char *key, wbplayerstruct_t &h, wbplayerstruct_t *def)
{
int i=hubdata.Size();
arc << i;
if (i>0)
if (arc.BeginObject(key))
{
if (arc.IsStoring()) arc.Write(&hubdata[0], i * sizeof(FHubInfo));
else
{
hubdata.Resize(i);
arc.Read(&hubdata[0], i * sizeof(FHubInfo));
}
arc("in", h.in)
("kills", h.skills)
("items", h.sitems)
("secrets", h.ssecret)
("time", h.stime)
("fragcount", h.fragcount)
.Array("frags", h.frags, MAXPLAYERS)
.EndObject();
}
else hubdata.Clear();
return arc;
}
void G_WriteHubInfo (FILE *file)
FSerializer &Serialize(FSerializer &arc, const char *key, FHubInfo &h, FHubInfo *def)
{
FPNGChunkArchive arc(file, HUBS_ID);
G_SerializeHub(arc);
if (arc.BeginObject(key))
{
arc("levelnum", h.levelnum)
("maxkills", h.maxkills)
("maxitems", h.maxitems)
("maxsecret", h.maxsecret)
("maxfrags", h.maxfrags)
.Array("players", h.plyr, MAXPLAYERS)
.EndObject();
}
return arc;
}
void G_ReadHubInfo (PNGHandle *png)
void G_SerializeHub(FSerializer &arc)
{
int chunklen;
if ((chunklen = M_FindPNGChunk (png, HUBS_ID)) != 0)
{
FPNGChunkArchive arc (png->File->GetFile(), HUBS_ID, chunklen);
G_SerializeHub(arc);
}
arc("hubinfo", hubdata);
}
void G_ClearHubInfo()

View file

@ -1,14 +1,11 @@
#ifndef __G_HUB_H
#define __G_HUB_H
#include <stdio.h>
struct PNGHandle;
struct cluster_info_t;
struct wbstartstruct_t;
class FSerializer;
void G_WriteHubInfo (FILE *file);
void G_ReadHubInfo (PNGHandle *png);
void G_SerializeHub (FSerializer &file);
void G_LeavingHub(int mode, cluster_info_t * cluster, struct wbstartstruct_t * wbs);
#endif

View file

@ -81,10 +81,10 @@
#include "a_sharedglobal.h"
#include "a_strifeglobal.h"
#include "r_data/colormaps.h"
#include "farchive.h"
#include "r_renderer.h"
#include "r_utility.h"
#include "p_spec.h"
#include "serializer.h"
#include "gi.h"
@ -93,7 +93,7 @@
void STAT_StartNewGame(const char *lev);
void STAT_ChangeLevel(const char *newl);
EXTERN_CVAR(Bool, save_formatted)
EXTERN_CVAR (Float, sv_gravity)
EXTERN_CVAR (Float, sv_aircontrol)
EXTERN_CVAR (Int, disableautosave)
@ -822,7 +822,7 @@ void G_DoCompleted (void)
}
else
{ // Make sure we don't have a snapshot lying around from before.
level.info->ClearSnapshot();
level.info->Snapshot.Clean();
}
}
else
@ -1477,135 +1477,6 @@ void G_AirControlChanged ()
}
}
//==========================================================================
//
//
//==========================================================================
void gl_SerializeGlobals(FArchive &arc);
void G_SerializeLevel (FArchive &arc, bool hubLoad)
{
int i = level.totaltime;
Renderer->StartSerialize(arc);
if (arc.IsLoading()) P_DestroyThinkers(hubLoad);
gl_SerializeGlobals(arc);
arc << level.flags
<< level.flags2
<< level.fadeto
<< level.found_secrets
<< level.found_items
<< level.killed_monsters
<< level.gravity
<< level.aircontrol
<< level.teamdamage
<< level.maptime
<< i;
// Hub transitions must keep the current total time
if (!hubLoad)
level.totaltime = i;
arc << level.skytexture1 << level.skytexture2;
if (arc.IsLoading())
{
sky1texture = level.skytexture1;
sky2texture = level.skytexture2;
R_InitSkyMap();
}
G_AirControlChanged ();
BYTE t;
// Does this level have scrollers?
if (arc.IsStoring ())
{
t = level.Scrolls ? 1 : 0;
arc << t;
}
else
{
arc << t;
if (level.Scrolls)
{
delete[] level.Scrolls;
level.Scrolls = NULL;
}
if (t)
{
level.Scrolls = new FSectorScrollValues[numsectors];
memset (level.Scrolls, 0, sizeof(level.Scrolls)*numsectors);
}
}
FBehavior::StaticSerializeModuleStates (arc);
if (arc.IsLoading()) interpolator.ClearInterpolations();
P_SerializeWorld(arc);
P_SerializeThinkers (arc, hubLoad);
P_SerializeWorldActors(arc); // serializing actor pointers in the world data must be done after SerializeWorld has restored the entire sector state, otherwise LinkToWorld may fail.
P_SerializePolyobjs (arc);
P_SerializeSubsectors(arc);
StatusBar->Serialize (arc);
arc << level.total_monsters << level.total_items << level.total_secrets;
// Does this level have custom translations?
FRemapTable *trans;
WORD w;
if (arc.IsStoring ())
{
for (unsigned int i = 0; i < translationtables[TRANSLATION_LevelScripted].Size(); ++i)
{
trans = translationtables[TRANSLATION_LevelScripted][i];
if (trans != NULL && !trans->IsIdentity())
{
w = WORD(i);
arc << w;
trans->Serialize(arc);
}
}
w = 0xffff;
arc << w;
}
else
{
while (arc << w, w != 0xffff)
{
trans = translationtables[TRANSLATION_LevelScripted].GetVal(w);
if (trans == NULL)
{
trans = new FRemapTable;
translationtables[TRANSLATION_LevelScripted].SetVal(w, trans);
}
trans->Serialize(arc);
}
}
// This must be saved, too, of course!
FCanvasTextureInfo::Serialize (arc);
AM_SerializeMarkers(arc);
P_SerializePlayers (arc, hubLoad);
P_SerializeSounds (arc);
if (arc.IsLoading())
{
for (i = 0; i < numsectors; i++)
{
P_Recalculate3DFloors(&sectors[i]);
}
for (i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].mo != NULL)
{
players[i].mo->SetupWeaponSlots();
}
}
}
Renderer->EndSerialize(arc);
}
//==========================================================================
//
// Archives the current level
@ -1614,19 +1485,18 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
void G_SnapshotLevel ()
{
if (level.info->snapshot)
delete level.info->snapshot;
level.info->Snapshot.Clean();
if (level.info->isValid())
{
level.info->snapshotVer = SAVEVER;
level.info->snapshot = new FCompressedMemFile;
level.info->snapshot->Open ();
FSerializer arc;
FArchive arc (*level.info->snapshot);
SaveVersion = SAVEVER;
G_SerializeLevel (arc, false);
if (arc.OpenWriter(save_formatted))
{
SaveVersion = SAVEVER;
G_SerializeLevel(arc, false);
level.info->Snapshot = arc.GetCompressedOutput();
}
}
}
@ -1639,18 +1509,15 @@ void G_SnapshotLevel ()
void G_UnSnapshotLevel (bool hubLoad)
{
if (level.info->snapshot == NULL)
if (level.info->Snapshot.mBuffer == nullptr)
return;
if (level.info->isValid())
{
SaveVersion = level.info->snapshotVer;
level.info->snapshot->Reopen ();
FArchive arc (*level.info->snapshot);
if (hubLoad)
arc.SetHubTravel ();
FSerializer arc;
if (!arc.OpenReader(&level.info->Snapshot)) return;
G_SerializeLevel (arc, hubLoad);
arc.Close ();
level.FromSnapshot = true;
TThinkerIterator<APlayerPawn> it;
@ -1680,7 +1547,7 @@ void G_UnSnapshotLevel (bool hubLoad)
}
}
// No reason to keep the snapshot around once the level's been entered.
level.info->ClearSnapshot();
level.info->Snapshot.Clean();
if (hubLoad)
{
// Unlock ACS global strings that were locked when the snapshot was made.
@ -1693,10 +1560,28 @@ void G_UnSnapshotLevel (bool hubLoad)
//
//==========================================================================
static void writeSnapShot (FArchive &arc, level_info_t *i)
void G_WriteSnapshots(TArray<FString> &filenames, TArray<FCompressedBuffer> &buffers)
{
arc << i->snapshotVer << i->MapName;
i->snapshot->Serialize (arc);
unsigned int i;
FString filename;
for (i = 0; i < wadlevelinfos.Size(); i++)
{
if (wadlevelinfos[i].Snapshot.mCompressedSize > 0)
{
filename.Format("%s.map.json", wadlevelinfos[i].MapName.GetChars());
filename.ToLower();
filenames.Push(filename);
buffers.Push(wadlevelinfos[i].Snapshot);
}
}
if (TheDefaultLevelInfo.Snapshot.mCompressedSize > 0)
{
filename.Format("%s.mapd.json", TheDefaultLevelInfo.MapName.GetChars());
filename.ToLower();
filenames.Push(filename);
buffers.Push(TheDefaultLevelInfo.Snapshot);
}
}
//==========================================================================
@ -1704,70 +1589,39 @@ static void writeSnapShot (FArchive &arc, level_info_t *i)
//
//==========================================================================
void G_WriteSnapshots (FILE *file)
void G_WriteVisited(FSerializer &arc)
{
unsigned int i;
for (i = 0; i < wadlevelinfos.Size(); i++)
if (arc.BeginArray("visited"))
{
if (wadlevelinfos[i].snapshot)
// Write out which levels have been visited
for (auto & wi : wadlevelinfos)
{
FPNGChunkArchive arc (file, SNAP_ID);
writeSnapShot (arc, (level_info_t *)&wadlevelinfos[i]);
}
}
if (TheDefaultLevelInfo.snapshot != NULL)
{
FPNGChunkArchive arc (file, DSNP_ID);
writeSnapShot(arc, &TheDefaultLevelInfo);
}
FPNGChunkArchive *arc = NULL;
// Write out which levels have been visited
for (i = 0; i < wadlevelinfos.Size(); ++i)
{
if (wadlevelinfos[i].flags & LEVEL_VISITED)
{
if (arc == NULL)
if (wi.flags & LEVEL_VISITED)
{
arc = new FPNGChunkArchive (file, VIST_ID);
arc.AddString(nullptr, wi.MapName);
}
(*arc) << wadlevelinfos[i].MapName;
}
}
if (arc != NULL)
{
FString empty = "";
(*arc) << empty;
delete arc;
arc.EndArray();
}
// Store player classes to be used when spawning a random class
if (multiplayer)
{
FPNGChunkArchive arc2 (file, RCLS_ID);
for (i = 0; i < MAXPLAYERS; ++i)
{
SBYTE cnum = SinglePlayerClass[i];
arc2 << cnum;
}
arc.Array("randomclasses", SinglePlayerClass, MAXPLAYERS);
}
// Store player classes that are currently in use
FPNGChunkArchive arc3 (file, PCLS_ID);
for (i = 0; i < MAXPLAYERS; ++i)
if (arc.BeginObject("playerclasses"))
{
BYTE pnum;
if (playeringame[i])
for (int i = 0; i < MAXPLAYERS; ++i)
{
pnum = i;
arc3 << pnum;
arc3.UserWriteClass (players[i].cls);
if (playeringame[i])
{
FString key;
key.Format("%d", i);
arc(key, players[i].cls);
}
}
pnum = 255;
arc3 << pnum;
arc.EndObject();
}
}
@ -1776,95 +1630,89 @@ void G_WriteSnapshots (FILE *file)
//
//==========================================================================
void G_ReadSnapshots (PNGHandle *png)
void G_ReadSnapshots(FResourceFile *resf)
{
DWORD chunkLen;
FString MapName;
level_info_t *i;
G_ClearSnapshots ();
G_ClearSnapshots();
chunkLen = (DWORD)M_FindPNGChunk (png, SNAP_ID);
while (chunkLen != 0)
for (unsigned j = 0; j < resf->LumpCount(); j++)
{
FPNGChunkArchive arc (png->File->GetFile(), SNAP_ID, chunkLen);
DWORD snapver;
arc << snapver;
arc << MapName;
i = FindLevelInfo (MapName);
i->snapshotVer = snapver;
i->snapshot = new FCompressedMemFile;
i->snapshot->Serialize (arc);
chunkLen = (DWORD)M_NextPNGChunk (png, SNAP_ID);
}
chunkLen = (DWORD)M_FindPNGChunk (png, DSNP_ID);
if (chunkLen != 0)
{
FPNGChunkArchive arc (png->File->GetFile(), DSNP_ID, chunkLen);
DWORD snapver;
arc << snapver;
arc << MapName;
TheDefaultLevelInfo.snapshotVer = snapver;
TheDefaultLevelInfo.snapshot = new FCompressedMemFile;
TheDefaultLevelInfo.snapshot->Serialize (arc);
}
chunkLen = (DWORD)M_FindPNGChunk (png, VIST_ID);
if (chunkLen != 0)
{
FPNGChunkArchive arc (png->File->GetFile(), VIST_ID, chunkLen);
while (arc << MapName, MapName.Len() > 0)
FResourceLump * resl = resf->GetLump(j);
if (resl != nullptr)
{
i = FindLevelInfo(MapName);
i->flags |= LEVEL_VISITED;
auto ptr = strstr(resl->FullName, ".map.json");
if (ptr != nullptr)
{
ptrdiff_t maplen = ptr - resl->FullName.GetChars();
FString mapname(resl->FullName.GetChars(), (size_t)maplen);
i = FindLevelInfo(mapname);
if (i != nullptr)
{
i->Snapshot = resl->GetRawData();
}
}
else
{
auto ptr = strstr(resl->FullName, ".mapd.json");
if (ptr != nullptr)
{
ptrdiff_t maplen = ptr - resl->FullName.GetChars();
FString mapname(resl->FullName.GetChars(), (size_t)maplen);
TheDefaultLevelInfo.Snapshot = resl->GetRawData();
}
}
}
}
chunkLen = (DWORD)M_FindPNGChunk (png, RCLS_ID);
if (chunkLen != 0)
{
FPNGChunkArchive arc (png->File->GetFile(), PCLS_ID, chunkLen);
SBYTE cnum;
for (DWORD j = 0; j < chunkLen; ++j)
{
arc << cnum;
SinglePlayerClass[j] = cnum;
}
}
chunkLen = (DWORD)M_FindPNGChunk (png, PCLS_ID);
if (chunkLen != 0)
{
FPNGChunkArchive arc (png->File->GetFile(), RCLS_ID, chunkLen);
BYTE pnum;
arc << pnum;
while (pnum != 255)
{
arc.UserReadClass (players[pnum].cls);
arc << pnum;
}
}
png->File->ResetFilePtr();
}
//==========================================================================
//
//
//==========================================================================
void G_ReadVisited(FSerializer &arc)
{
if (arc.BeginArray("visited"))
{
for (int s = arc.ArraySize(); s > 0; s--)
{
FString str;
arc(nullptr, str);
auto i = FindLevelInfo(str);
if (i != nullptr) i->flags |= LEVEL_VISITED;
}
arc.EndArray();
}
arc.Array("randomclasses", SinglePlayerClass, MAXPLAYERS);
if (arc.BeginObject("playerclasses"))
{
for (int i = 0; i < MAXPLAYERS; ++i)
{
FString key;
key.Format("%d", i);
arc(key, players[i].cls);
}
arc.EndObject();
}
}
//==========================================================================
//
//
//==========================================================================
CCMD(listsnapshots)
{
for (unsigned i = 0; i < wadlevelinfos.Size(); ++i)
{
FCompressedMemFile *snapshot = wadlevelinfos[i].snapshot;
if (snapshot != NULL)
FCompressedBuffer *snapshot = &wadlevelinfos[i].Snapshot;
if (snapshot->mBuffer != nullptr)
{
unsigned int comp, uncomp;
snapshot->GetSizes(comp, uncomp);
Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].MapName.GetChars(), comp, uncomp);
Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].MapName.GetChars(), snapshot->mCompressedSize, snapshot->mSize);
}
}
}
@ -1874,38 +1722,32 @@ CCMD(listsnapshots)
//
//==========================================================================
static void writeDefereds (FArchive &arc, level_info_t *i)
void P_WriteACSDefereds (FSerializer &arc)
{
arc << i->MapName << i->defered;
}
bool found = false;
//==========================================================================
//
//
//==========================================================================
void P_WriteACSDefereds (FILE *file)
{
FPNGChunkArchive *arc = NULL;
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
// only write this stuff if needed
for (auto &wi : wadlevelinfos)
{
if (wadlevelinfos[i].defered)
if (wi.deferred.Size() > 0)
{
if (arc == NULL)
found = true;
break;
}
}
if (found && arc.BeginObject("deferred"))
{
for (auto &wi : wadlevelinfos)
{
if (wi.deferred.Size() > 0)
{
arc = new FPNGChunkArchive (file, ACSD_ID);
if (wi.deferred.Size() > 0)
{
arc(wi.MapName, wi.deferred);
}
}
writeDefereds (*arc, (level_info_t *)&wadlevelinfos[i]);
}
}
if (arc != NULL)
{
// Signal end of defereds
FString empty = "";
(*arc) << empty;
delete arc;
arc.EndObject();
}
}
@ -1914,28 +1756,27 @@ void P_WriteACSDefereds (FILE *file)
//
//==========================================================================
void P_ReadACSDefereds (PNGHandle *png)
void P_ReadACSDefereds (FSerializer &arc)
{
FString MapName;
size_t chunklen;
P_RemoveDefereds ();
if ((chunklen = M_FindPNGChunk (png, ACSD_ID)) != 0)
if (arc.BeginObject("deferred"))
{
FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen);
const char *key;
while (arc << MapName, MapName.Len() > 0)
while ((key = arc.GetKey()))
{
level_info_t *i = FindLevelInfo(MapName);
level_info_t *i = FindLevelInfo(key);
if (i == NULL)
{
I_Error("Unknown map '%s' in savegame", MapName.GetChars());
I_Error("Unknown map '%s' in savegame", key);
}
arc << i->defered;
arc(nullptr, i->deferred);
}
arc.EndObject();
}
png->File->ResetFilePtr();
}
@ -1947,9 +1788,9 @@ void P_ReadACSDefereds (PNGHandle *png)
void FLevelLocals::Tick ()
{
// Reset carry sectors
if (Scrolls != NULL)
if (Scrolls.Size() > 0)
{
memset (Scrolls, 0, sizeof(*Scrolls)*numsectors);
memset (&Scrolls[0], 0, sizeof(Scrolls[0])*Scrolls.Size());
}
}
@ -1964,10 +1805,10 @@ void FLevelLocals::AddScroller (int secnum)
{
return;
}
if (Scrolls == NULL)
if (Scrolls.Size() == 0)
{
Scrolls = new FSectorScrollValues[numsectors];
memset (Scrolls, 0, sizeof(*Scrolls)*numsectors);
Scrolls.Resize(numsectors);
memset (&Scrolls[0], 0, sizeof(Scrolls[0])*numsectors);
}
}

View file

@ -38,7 +38,9 @@
#include "doomdef.h"
#include "sc_man.h"
#include "s_sound.h"
#include "p_acs.h"
#include "textures/textures.h"
#include "resourcefiles/file_zip.h"
struct level_info_t;
struct cluster_info_t;
@ -223,8 +225,6 @@ enum ELevelFlags : unsigned int
};
struct acsdefered_t;
struct FSpecialAction
{
FName Type; // this is initialized before the actors...
@ -232,7 +232,6 @@ struct FSpecialAction
int Args[5]; // must allow 16 bit tags for 666 & 667!
};
class FCompressedMemFile;
class DScroller;
class FScanner;
@ -295,9 +294,8 @@ struct level_info_t
FString LevelName;
SBYTE WallVertLight, WallHorizLight;
int musicorder;
FCompressedMemFile *snapshot;
DWORD snapshotVer;
struct acsdefered_t *defered;
FCompressedBuffer Snapshot;
TArray<acsdefered_t> deferred;
float skyspeed1;
float skyspeed2;
DWORD fadeto;
@ -346,14 +344,16 @@ struct level_info_t
}
~level_info_t()
{
ClearSnapshot();
Snapshot.Clean();
ClearDefered();
}
void Reset();
bool isValid();
FString LookupLevelName ();
void ClearSnapshot();
void ClearDefered();
void ClearDefered()
{
deferred.Clear();
}
level_info_t *CheckLevelRedirect ();
template<class T>
@ -375,17 +375,12 @@ struct level_info_t
}
};
// [RH] These get zeroed every tic and are updated by thinkers.
struct FSectorScrollValues
{
DVector2 Scroll;
};
struct FLevelLocals
{
void Tick ();
void AddScroller (int secnum);
BYTE md5[16]; // for savegame validation. If the MD5 does not match the savegame won't be loaded.
int time; // time in the hub
int maptime; // time in the map
int totaltime; // time in the game
@ -436,7 +431,7 @@ struct FLevelLocals
int airsupply;
int DefaultEnvironment; // Default sound environment.
FSectorScrollValues *Scrolls; // NULL if no DScrollers in this level
TArray<DVector2> Scrolls; // NULL if no DScrollers in this level
SBYTE WallVertLight; // Light diffs for vert/horiz walls
SBYTE WallHorizLight;
@ -537,9 +532,10 @@ void G_ClearSnapshots (void);
void P_RemoveDefereds ();
void G_SnapshotLevel (void);
void G_UnSnapshotLevel (bool keepPlayers);
struct PNGHandle;
void G_ReadSnapshots (PNGHandle *png);
void G_WriteSnapshots (FILE *file);
void G_ReadSnapshots (FResourceFile *);
void G_WriteSnapshots (TArray<FString> &, TArray<FCompressedBuffer> &);
void G_WriteVisited(FSerializer &arc);
void G_ReadVisited(FSerializer &arc);
void G_ClearHubInfo();
enum ESkillProperty

View file

@ -45,7 +45,6 @@
#include "i_system.h"
#include "gi.h"
#include "gstrings.h"
#include "farchive.h"
#include "p_acs.h"
#include "doomstat.h"
#include "d_player.h"
@ -196,7 +195,7 @@ void G_ClearSnapshots (void)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{
wadlevelinfos[i].ClearSnapshot();
wadlevelinfos[i].Snapshot.Clean();
}
// Since strings are only locked when snapshotting a level, unlock them
// all now, since we got rid of all the snapshots that cared about them.
@ -248,9 +247,8 @@ void level_info_t::Reset()
WallVertLight = +8;
F1Pic = "";
musicorder = 0;
snapshot = NULL;
snapshotVer = 0;
defered = 0;
Snapshot = { 0,0,0,0,0,nullptr };
deferred.Clear();
skyspeed1 = skyspeed2 = 0.f;
fadeto = 0;
outsidefog = 0xff000000;
@ -334,34 +332,6 @@ FString level_info_t::LookupLevelName()
}
//==========================================================================
//
//
//==========================================================================
void level_info_t::ClearSnapshot()
{
if (snapshot != NULL) delete snapshot;
snapshot = NULL;
}
//==========================================================================
//
//
//==========================================================================
void level_info_t::ClearDefered()
{
acsdefered_t *def = defered;
while (def)
{
acsdefered_t *next = def->next;
delete def;
def = next;
}
defered = NULL;
}
//==========================================================================
//
//

View file

@ -11,9 +11,9 @@
#include "thingdef/thingdef.h"
#include "g_level.h"
#include "doomstat.h"
#include "farchive.h"
#include "a_pickups.h"
#include "d_player.h"
#include "serializer.h"
#define MAULATORTICS (25*35)
@ -79,10 +79,10 @@ void AMinotaurFriend::BeginPlay ()
StartTime = -1;
}
void AMinotaurFriend::Serialize (FArchive &arc)
void AMinotaurFriend::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << StartTime;
arc("starttime", StartTime);
}
void AMinotaurFriend::Die (AActor *source, AActor *inflictor, int dmgflags)

View file

@ -23,7 +23,8 @@ public:
void Die (AActor *source, AActor *inflictor, int dmgflags);
bool OkayToSwitchTarget (AActor *other);
void BeginPlay ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
};
#endif //__RAVENSHARED_H__

View file

@ -11,7 +11,7 @@
#include "p_enemy.h"
#include "statnums.h"
#include "templates.h"
#include "farchive.h"
#include "serializer.h"
#include "r_data/r_translate.h"
static FRandom pr_freezedeath ("FreezeDeath");
@ -361,7 +361,7 @@ class DCorpsePointer : public DThinker
public:
DCorpsePointer (AActor *ptr);
void Destroy ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
TObjPtr<AActor> Corpse;
DWORD Count; // Only the first corpse pointer's count is valid.
private:
@ -435,10 +435,11 @@ void DCorpsePointer::Destroy ()
Super::Destroy ();
}
void DCorpsePointer::Serialize (FArchive &arc)
void DCorpsePointer::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc << Corpse << Count;
arc("corpse", Corpse)
("count", Count);
}

View file

@ -6,7 +6,7 @@
#include "templates.h"
#include "g_level.h"
#include "d_player.h"
#include "farchive.h"
#include "serializer.h"
IMPLEMENT_CLASS (AArmor)
@ -21,10 +21,17 @@ IMPLEMENT_CLASS (AHexenArmor)
//
//===========================================================================
void ABasicArmor::Serialize (FArchive &arc)
void ABasicArmor::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << SavePercent << BonusCount << MaxAbsorb << MaxFullAbsorb << AbsorbCount << ArmorType << ActualSaveAmount;
auto def = (ABasicArmor *)GetDefault();
arc("savepercent", SavePercent, def->SavePercent)
("bonuscount", BonusCount, def->BonusCount)
("maxabsorb", MaxAbsorb, def->MaxAbsorb)
("maxfullabsorb", MaxFullAbsorb, def->MaxFullAbsorb)
("absorbcount", AbsorbCount, def->AbsorbCount)
("armortype", ArmorType, def->ArmorType)
("actualsaveamount", ActualSaveAmount, def->ActualSaveAmount);
}
//===========================================================================
@ -192,11 +199,15 @@ void ABasicArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
//
//===========================================================================
void ABasicArmorPickup::Serialize (FArchive &arc)
void ABasicArmorPickup::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << SavePercent << SaveAmount << MaxAbsorb << MaxFullAbsorb;
arc << DropTime;
auto def = (ABasicArmorPickup *)GetDefault();
arc("savepercent", SavePercent, def->SavePercent)
("saveamount", SaveAmount, def->SaveAmount)
("maxabsorb", MaxAbsorb, def->MaxAbsorb)
("maxfullabsorb", MaxFullAbsorb, def->MaxFullAbsorb);
}
//===========================================================================
@ -274,11 +285,17 @@ bool ABasicArmorPickup::Use (bool pickup)
//
//===========================================================================
void ABasicArmorBonus::Serialize (FArchive &arc)
void ABasicArmorBonus::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << SavePercent << SaveAmount << MaxSaveAmount << BonusCount << BonusMax
<< MaxAbsorb << MaxFullAbsorb;
auto def = (ABasicArmorBonus *)GetDefault();
arc("savepercent", SavePercent, def->SavePercent)
("saveamount", SaveAmount, def->SaveAmount)
("maxsaveamount", MaxSaveAmount, def->MaxSaveAmount)
("bonuscount", BonusCount, def->BonusCount)
("bonusmax", BonusMax, def->BonusMax)
("maxabsorb", MaxAbsorb, def->MaxAbsorb)
("maxfullabsorb", MaxFullAbsorb, def->MaxFullAbsorb);
}
//===========================================================================
@ -371,13 +388,12 @@ bool ABasicArmorBonus::Use (bool pickup)
//
//===========================================================================
void AHexenArmor::Serialize (FArchive &arc)
void AHexenArmor::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << Slots[0] << Slots[1] << Slots[2] << Slots[3]
<< Slots[4]
<< SlotsIncrement[0] << SlotsIncrement[1] << SlotsIncrement[2]
<< SlotsIncrement[3];
auto def = (AHexenArmor *)GetDefault();
arc.Array("slots", Slots, def->Slots, 5, true)
.Array("slotsincrement", SlotsIncrement, def->SlotsIncrement, 4);
}
//===========================================================================

View file

@ -19,7 +19,7 @@
#include "g_level.h"
#include "doomstat.h"
#include "v_palette.h"
#include "farchive.h"
#include "serializer.h"
#include "r_utility.h"
#include "r_data/colormaps.h"
@ -101,12 +101,15 @@ bool APowerupGiver::Use (bool pickup)
//
//===========================================================================
void APowerupGiver::Serialize (FArchive &arc)
void APowerupGiver::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << PowerupType;
arc << EffectTics << BlendColor << Mode;
arc << Strength;
auto def = (APowerupGiver*)GetDefault();
arc("poweruptype", PowerupType, def->PowerupType)
("effecttics", EffectTics, def->EffectTics)
("blendcolor", BlendColor, def->BlendColor)
("mode", Mode, def->Mode)
("strength", Strength, def->Strength);
}
// Powerup -------------------------------------------------------------------
@ -136,11 +139,14 @@ void APowerup::Tick ()
//
//===========================================================================
void APowerup::Serialize (FArchive &arc)
void APowerup::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << EffectTics << BlendColor << Mode;
arc << Strength;
auto def = (APowerup*)GetDefault();
arc("effecttics", EffectTics, def->EffectTics)
("blendcolor", BlendColor, def->BlendColor)
("mode", Mode, def->Mode)
("strength", Strength, def->Strength);
}
//===========================================================================
@ -901,10 +907,11 @@ IMPLEMENT_CLASS (APowerTorch)
//
//===========================================================================
void APowerTorch::Serialize (FArchive &arc)
void APowerTorch::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << NewTorch << NewTorchDelta;
arc("newtorch", NewTorch)
("newtorchdelta", NewTorchDelta);
}
//===========================================================================
@ -963,10 +970,10 @@ IMPLEMENT_CLASS (APowerFlight)
//
//===========================================================================
void APowerFlight::Serialize (FArchive &arc)
void APowerFlight::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << HitCenterFrame;
arc("hitcenterframe", HitCenterFrame);
}
//===========================================================================
@ -1217,10 +1224,10 @@ IMPLEMENT_CLASS (APowerSpeed)
//
//===========================================================================
void APowerSpeed::Serialize(FArchive &arc)
void APowerSpeed::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << SpeedFlags;
arc("speedflags", SpeedFlags);
}
//===========================================================================
@ -1899,11 +1906,14 @@ IMPLEMENT_CLASS(APowerMorph)
//
//===========================================================================
void APowerMorph::Serialize (FArchive &arc)
void APowerMorph::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << PlayerClass << MorphStyle << MorphFlash << UnMorphFlash;
arc << Player;
arc("playerclass", PlayerClass)
("morphstyle", MorphStyle)
("morphflash", MorphFlash)
("unmorphflash", UnMorphFlash)
("player", Player);
}
//===========================================================================

View file

@ -16,7 +16,8 @@ public:
virtual bool HandlePickup (AInventory *item);
virtual AInventory *CreateCopy (AActor *other);
virtual AInventory *CreateTossable ();
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual void OwnerDied ();
virtual bool GetNoTeleportFreeze();
virtual PalEntry GetBlend ();
@ -51,7 +52,8 @@ class APowerupGiver : public AInventory
DECLARE_CLASS_WITH_META (APowerupGiver, AInventory, PClassPowerupGiver)
public:
virtual bool Use (bool pickup);
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
PClassActor *PowerupType;
@ -121,7 +123,8 @@ class APowerTorch : public APowerLightAmp
{
DECLARE_CLASS (APowerTorch, APowerLightAmp)
public:
void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
protected:
void DoEffect ();
int NewTorch, NewTorchDelta;
@ -132,7 +135,8 @@ class APowerFlight : public APowerup
DECLARE_CLASS (APowerFlight, APowerup)
public:
bool DrawPowerup (int x, int y);
void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
protected:
void InitEffect ();
@ -155,7 +159,8 @@ class APowerSpeed : public APowerup
DECLARE_CLASS (APowerSpeed, APowerup)
protected:
void DoEffect ();
void Serialize(FArchive &arc);
virtual void Serialize(FSerializer &arc);
double GetSpeedFactor();
public:
int SpeedFlags;
@ -272,7 +277,8 @@ class APowerMorph : public APowerup
{
DECLARE_CLASS( APowerMorph, APowerup )
public:
void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
void SetNoCallUndoMorph() { bNoCallUndoMorph = true; }
FNameNoInit PlayerClass, MorphFlash, UnMorphFlash;

View file

@ -36,7 +36,7 @@
#include "info.h"
#include "a_sharedglobal.h"
#include "p_local.h"
#include "farchive.h"
#include "serializer.h"
#include "math/cmath.h"
/*
@ -55,7 +55,8 @@ public:
void PostBeginPlay ();
void Tick ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
protected:
DAngle Center;
DAngle Acc;
@ -65,10 +66,13 @@ protected:
IMPLEMENT_CLASS (ASecurityCamera)
void ASecurityCamera::Serialize (FArchive &arc)
void ASecurityCamera::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << Center << Acc << Delta << Range;
arc("center", Center)
("acc", Acc)
("delta", Delta)
("range", Range);
}
void ASecurityCamera::PostBeginPlay ()
@ -114,17 +118,18 @@ public:
void PostBeginPlay ();
void Tick ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
protected:
DAngle MaxPitchChange;
};
IMPLEMENT_CLASS (AAimingCamera)
void AAimingCamera::Serialize (FArchive &arc)
void AAimingCamera::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << MaxPitchChange;
arc("maxpitchchange", MaxPitchChange);
}
void AAimingCamera::PostBeginPlay ()

View file

@ -44,8 +44,9 @@
#include "d_net.h"
#include "colormatcher.h"
#include "v_palette.h"
#include "farchive.h"
#include "serializer.h"
#include "doomdata.h"
#include "r_state.h"
static double DecalWidth, DecalLeft, DecalRight;
static double SpreadZ;
@ -58,7 +59,8 @@ static int ImpactCount;
CVAR (Bool, cl_spreaddecals, true, CVAR_ARCHIVE)
IMPLEMENT_POINTY_CLASS (DBaseDecal)
DECLARE_POINTER(WallNext)
DECLARE_POINTER(WallPrev)
DECLARE_POINTER(WallNext)
END_POINTERS
IMPLEMENT_CLASS (DImpactDecal)
@ -75,7 +77,7 @@ DBaseDecal::DBaseDecal ()
DBaseDecal::DBaseDecal (double z)
: DThinker(STAT_DECAL),
WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(1.), ScaleY(1.), Alpha(1.),
AlphaColor(0), Translation(0), RenderFlags(0)
AlphaColor(0), Translation(0), RenderFlags(0), Side(nullptr), Sector(nullptr)
{
RenderStyle = STYLE_None;
PicNum.SetInvalid();
@ -83,8 +85,8 @@ DBaseDecal::DBaseDecal (double z)
DBaseDecal::DBaseDecal (int statnum, double z)
: DThinker(statnum),
WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(1.), ScaleY(1.), Alpha(1.),
AlphaColor(0), Translation(0), RenderFlags(0)
WallNext(nullptr), WallPrev(nullptr), LeftDistance(0), Z(z), ScaleX(1.), ScaleY(1.), Alpha(1.),
AlphaColor(0), Translation(0), RenderFlags(0), Side(nullptr), Sector(nullptr)
{
RenderStyle = STYLE_None;
PicNum.SetInvalid();
@ -92,17 +94,17 @@ DBaseDecal::DBaseDecal (int statnum, double z)
DBaseDecal::DBaseDecal (const AActor *basis)
: DThinker(STAT_DECAL),
WallNext(0), WallPrev(0), LeftDistance(0), Z(basis->Z()), ScaleX(basis->Scale.X), ScaleY(basis->Scale.Y),
WallNext(nullptr), WallPrev(nullptr), LeftDistance(0), Z(basis->Z()), ScaleX(basis->Scale.X), ScaleY(basis->Scale.Y),
Alpha(basis->Alpha), AlphaColor(basis->fillcolor), Translation(basis->Translation), PicNum(basis->picnum),
RenderFlags(basis->renderflags), RenderStyle(basis->RenderStyle)
RenderFlags(basis->renderflags), RenderStyle(basis->RenderStyle), Side(nullptr), Sector(nullptr)
{
}
DBaseDecal::DBaseDecal (const DBaseDecal *basis)
: DThinker(STAT_DECAL),
WallNext(0), WallPrev(0), LeftDistance(basis->LeftDistance), Z(basis->Z), ScaleX(basis->ScaleX),
WallNext(nullptr), WallPrev(nullptr), LeftDistance(basis->LeftDistance), Z(basis->Z), ScaleX(basis->ScaleX),
ScaleY(basis->ScaleY), Alpha(basis->Alpha), AlphaColor(basis->AlphaColor), Translation(basis->Translation),
PicNum(basis->PicNum), RenderFlags(basis->RenderFlags), RenderStyle(basis->RenderStyle)
PicNum(basis->PicNum), RenderFlags(basis->RenderFlags), RenderStyle(basis->RenderStyle), Side(nullptr), Sector(nullptr)
{
}
@ -114,64 +116,35 @@ void DBaseDecal::Destroy ()
void DBaseDecal::Remove ()
{
DBaseDecal **prev = WallPrev;
DBaseDecal *next = WallNext;
if (prev && (*prev = next))
next->WallPrev = prev;
WallPrev = NULL;
WallNext = NULL;
if (WallPrev == nullptr)
{
if (Side != nullptr) Side->AttachedDecals = WallNext;
}
else WallPrev->WallNext = WallNext;
if (WallNext != nullptr) WallNext->WallPrev = WallPrev;
WallPrev = nullptr;
WallNext = nullptr;
}
void DBaseDecal::Serialize (FArchive &arc)
void DBaseDecal::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << LeftDistance
<< Z
<< ScaleX << ScaleY
<< Alpha
<< AlphaColor
<< Translation
<< PicNum
<< RenderFlags
<< RenderStyle
<< Sector;
}
void DBaseDecal::SerializeChain (FArchive &arc, DBaseDecal **first)
{
DWORD numInChain;
DBaseDecal *fresh;
DBaseDecal **firstptr = first;
if (arc.IsLoading ())
{
numInChain = arc.ReadCount ();
while (numInChain--)
{
arc << fresh;
*firstptr = fresh;
fresh->WallPrev = firstptr;
firstptr = &fresh->WallNext;
}
}
else
{
numInChain = 0;
fresh = *firstptr;
while (fresh != NULL)
{
fresh = fresh->WallNext;
++numInChain;
}
arc.WriteCount (numInChain);
fresh = *firstptr;
while (numInChain--)
{
arc << fresh;
fresh = fresh->WallNext;
}
}
arc("wallprev", WallPrev)
("wallnext", WallNext)
("leftdistance", LeftDistance)
("z", Z)
("scalex", ScaleX)
("scaley", ScaleY)
("alpha", Alpha)
("alphacolor", AlphaColor)
("translation", Translation)
("picnum", PicNum)
("renderflags", RenderFlags)
("renderstyle", RenderStyle)
("side", Side)
("sector", Sector);
}
void DBaseDecal::GetXY (side_t *wall, double &ox, double &oy) const
@ -211,26 +184,18 @@ void DBaseDecal::SetShade (int r, int g, int b)
// Returns the texture the decal stuck to.
FTextureID DBaseDecal::StickToWall (side_t *wall, double x, double y, F3DFloor *ffloor)
{
// Stick the decal at the end of the chain so it appears on top
DBaseDecal *next, **prev;
Side = wall;
WallPrev = wall->AttachedDecals;
prev = &wall->AttachedDecals;
while (*prev != NULL)
while (WallPrev != nullptr && WallPrev->WallNext != nullptr)
{
next = *prev;
prev = &next->WallNext;
WallPrev = WallPrev->WallNext;
}
if (WallPrev != nullptr) WallPrev->WallNext = this;
else wall->AttachedDecals = this;
WallNext = nullptr;
*prev = this;
WallNext = NULL;
WallPrev = prev;
/*
WallNext = wall->AttachedDecals;
WallPrev = &wall->AttachedDecals;
if (WallNext)
WallNext->WallPrev = &WallNext;
wall->AttachedDecals = this;
*/
sector_t *front, *back;
line_t *line;
FTextureID tex;
@ -592,28 +557,6 @@ CUSTOM_CVAR (Int, cl_maxdecals, 1024, CVAR_ARCHIVE)
}
}
// Uses: target points to previous impact decal
// tracer points to next impact decal
//
// Note that this means we can't simply serialize an impact decal as-is
// because doing so when many are present in a level could result in
// a lot of recursion and we would run out of stack. Not nice. So instead,
// the save game code calls DImpactDecal::SerializeAll to serialize a
// list of impact decals.
void DImpactDecal::SerializeTime (FArchive &arc)
{
if (arc.IsLoading ())
{
ImpactCount = 0;
}
}
void DImpactDecal::Serialize (FArchive &arc)
{
Super::Serialize (arc);
}
DImpactDecal::DImpactDecal ()
: DBaseDecal (STAT_AUTODECAL, 0.)
{

View file

@ -1,7 +1,7 @@
#include "a_sharedglobal.h"
#include "g_level.h"
#include "d_player.h"
#include "farchive.h"
#include "serializer.h"
IMPLEMENT_POINTY_CLASS (DFlashFader)
DECLARE_POINTER (ForWho)
@ -26,13 +26,13 @@ void DFlashFader::Destroy ()
Super::Destroy();
}
void DFlashFader::Serialize (FArchive &arc)
void DFlashFader::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << TotalTics << StartTic << ForWho;
for (int i = 1; i >= 0; --i)
for (int j = 3; j >= 0; --j)
arc << Blends[i][j];
arc("totaltics", TotalTics)
("starttic", StartTic)
("forwho", ForWho)
.Array("blends", Blends[0], 8);
}
void DFlashFader::Tick ()

View file

@ -9,7 +9,7 @@
#include "r_sky.h"
#include "g_level.h"
#include "r_state.h"
#include "farchive.h"
#include "serializer.h"
static FRandom pr_lightning ("Lightning");
@ -19,44 +19,24 @@ DLightningThinker::DLightningThinker ()
: DThinker (STAT_LIGHTNING)
{
Stopped = false;
LightningLightLevels = NULL;
LightningFlashCount = 0;
NextLightningFlash = ((pr_lightning()&15)+5)*35; // don't flash at level start
LightningLightLevels = new short[numsectors];
clearbufshort(LightningLightLevels, numsectors, SHRT_MAX);
LightningLightLevels.Resize(numsectors);
clearbufshort(&LightningLightLevels[0], numsectors, SHRT_MAX);
}
DLightningThinker::~DLightningThinker ()
{
if (LightningLightLevels != NULL)
{
delete[] LightningLightLevels;
}
}
void DLightningThinker::Serialize (FArchive &arc)
void DLightningThinker::Serialize(FSerializer &arc)
{
int i;
short *lights;
Super::Serialize (arc);
arc << Stopped << NextLightningFlash << LightningFlashCount;
if (arc.IsLoading ())
{
if (LightningLightLevels != NULL)
{
delete[] LightningLightLevels;
}
LightningLightLevels = new short[numsectors];
}
lights = LightningLightLevels;
for (i = numsectors; i > 0; ++lights, --i)
{
arc << *lights;
}
arc("stopped", Stopped)
("next", NextLightningFlash)
("count", LightningFlashCount)
("levels", LightningLightLevels);
}
void DLightningThinker::Tick ()
@ -107,7 +87,7 @@ void DLightningThinker::LightningFlash ()
tempSec->SetLightLevel(LightningLightLevels[j]);
}
}
clearbufshort(LightningLightLevels, numsectors, SHRT_MAX);
clearbufshort(&LightningLightLevels[0], numsectors, SHRT_MAX);
level.flags &= ~LEVEL_SWAPSKIES;
}
return;

View file

@ -13,7 +13,7 @@ class DLightningThinker : public DThinker
public:
DLightningThinker ();
~DLightningThinker ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
void ForceLightning (int mode);
void TerminateLightning();
@ -24,7 +24,7 @@ protected:
int NextLightningFlash;
int LightningFlashCount;
bool Stopped;
short *LightningLightLevels;
TArray<short> LightningLightLevels;
};
void P_StartLightning ();

View file

@ -11,9 +11,10 @@
#include "a_morph.h"
#include "doomstat.h"
#include "g_level.h"
#include "farchive.h"
#include "serializer.h"
#include "p_enemy.h"
#include "d_player.h"
#include "r_data/sprites.h"
static FRandom pr_morphmonst ("MorphMonster");
@ -634,10 +635,16 @@ int AMorphProjectile::DoSpecialDamage (AActor *target, int damage, FName damaget
return -1;
}
void AMorphProjectile::Serialize (FArchive &arc)
void AMorphProjectile::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << PlayerClass << MonsterClass << Duration << MorphStyle << MorphFlash << UnMorphFlash;
auto def = (AMorphProjectile*)GetDefault();
arc("playerclass", PlayerClass, def->PlayerClass)
("monsterclass", MonsterClass, def->MonsterClass)
("duration", Duration, def->Duration)
("morphstyle", MorphStyle, def->MorphStyle)
("morphflash", MorphFlash, def->MorphFlash)
("unmorphflash", UnMorphFlash, def->UnMorphFlash);
}
@ -647,10 +654,14 @@ IMPLEMENT_POINTY_CLASS (AMorphedMonster)
DECLARE_POINTER (UnmorphedMe)
END_POINTERS
void AMorphedMonster::Serialize (FArchive &arc)
void AMorphedMonster::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << UnmorphedMe << UnmorphTime << MorphStyle << MorphExitFlash << FlagsSave;
arc("unmorphedme", UnmorphedMe)
("unmorphtime", UnmorphTime)
("morphstyle", MorphStyle)
("morphexitflash", MorphExitFlash)
("flagsave", FlagsSave);
}
void AMorphedMonster::Destroy ()

View file

@ -37,7 +37,7 @@
#include "p_local.h"
#include "p_lnspec.h"
#include "doomstat.h"
#include "farchive.h"
#include "serializer.h"
/*
== InterpolationPoint: node along a camera's path
@ -60,7 +60,8 @@ public:
AInterpolationPoint *ScanForLoop ();
void FormChain ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
TObjPtr<AInterpolationPoint> Next;
};
@ -69,10 +70,10 @@ IMPLEMENT_POINTY_CLASS (AInterpolationPoint)
DECLARE_POINTER (Next)
END_POINTERS
void AInterpolationPoint::Serialize (FArchive &arc)
void AInterpolationPoint::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << Next;
arc("next", Next);
}
void AInterpolationPoint::BeginPlay ()
@ -166,7 +167,8 @@ protected:
virtual bool Interpolate ();
virtual void NewNode ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
bool bActive, bJustStepped;
TObjPtr<AInterpolationPoint> PrevNode, CurrNode;
@ -179,10 +181,15 @@ IMPLEMENT_POINTY_CLASS (APathFollower)
DECLARE_POINTER (CurrNode)
END_POINTERS
void APathFollower::Serialize (FArchive &arc)
void APathFollower::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << bActive << bJustStepped << PrevNode << CurrNode << Time << HoldTime;
arc("active", bActive)
("juststepped", bJustStepped)
("prevnode", PrevNode)
("currnode", CurrNode)
("time", Time)
("holdtime", HoldTime);
}
// Interpolate between p2 and p3 along a Catmull-Rom spline
@ -577,7 +584,8 @@ class AMovingCamera : public APathFollower
public:
void PostBeginPlay ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
protected:
bool Interpolate ();
@ -588,10 +596,10 @@ IMPLEMENT_POINTY_CLASS (AMovingCamera)
DECLARE_POINTER (Activator)
END_POINTERS
void AMovingCamera::Serialize (FArchive &arc)
void AMovingCamera::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << Activator;
arc("activator", Activator);
}
void AMovingCamera::PostBeginPlay ()

View file

@ -18,9 +18,9 @@
#include "g_level.h"
#include "g_game.h"
#include "doomstat.h"
#include "farchive.h"
#include "d_player.h"
#include "p_spec.h"
#include "serializer.h"
static FRandom pr_restore ("RestorePos");
@ -89,10 +89,12 @@ IMPLEMENT_CLASS (AAmmo)
//
//===========================================================================
void AAmmo::Serialize (FArchive &arc)
void AAmmo::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << BackpackAmount << BackpackMaxAmount;
auto def = (AAmmo*)GetDefault();
arc("backpackamount", BackpackAmount, def->BackpackAmount)
("backpackmaxamount", BackpackMaxAmount, def->BackpackMaxAmount);
}
//===========================================================================
@ -514,10 +516,21 @@ void AInventory::Tick ()
//
//===========================================================================
void AInventory::Serialize (FArchive &arc)
void AInventory::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << Owner << Amount << MaxAmount << RespawnTics << ItemFlags << Icon << PickupSound << SpawnPointClass;
auto def = (AInventory*)GetDefault();
arc("owner", Owner)
("amount", Amount, def->Amount)
("maxamount", MaxAmount, def->MaxAmount)
("interhubamount", InterHubAmount, def->InterHubAmount)
("respawntics", RespawnTics, def->RespawnTics)
("itemflags", ItemFlags, def->ItemFlags)
("icon", Icon, def->Icon)
("pickupsound", PickupSound, def->PickupSound)
("spawnpointclass", SpawnPointClass, def->SpawnPointClass)
("droptime", DropTime, def->DropTime);
}
//===========================================================================
@ -1809,10 +1822,11 @@ bool AHealthPickup::Use (bool pickup)
//
//===========================================================================
void AHealthPickup::Serialize (FArchive &arc)
void AHealthPickup::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc << autousemode;
auto def = (AHealthPickup*)GetDefault();
arc("autousemode", autousemode, def->autousemode);
}
// Backpack -----------------------------------------------------------------
@ -1823,10 +1837,11 @@ void AHealthPickup::Serialize (FArchive &arc)
//
//===========================================================================
void ABackpackItem::Serialize (FArchive &arc)
void ABackpackItem::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << bDepleted;
auto def = (ABackpackItem*)GetDefault();
arc("bdepleted", bDepleted, def->bDepleted);
}
//===========================================================================

View file

@ -153,7 +153,8 @@ class AInventory : public AActor
HAS_OBJECT_POINTERS
public:
virtual void Touch (AActor *toucher);
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual void MarkPrecacheSounds() const;
virtual void BeginPlay ();
@ -185,7 +186,7 @@ public:
int RespawnTics; // Tics from pickup time to respawn time
FTextureID Icon; // Icon to show on status bar or HUD
int DropTime; // Countdown after dropping
const PClass *SpawnPointClass; // For respawning like Heretic's mace
PClassActor *SpawnPointClass; // For respawning like Heretic's mace
DWORD ItemFlags;
PClassActor *PickupFlash; // actor to spawn as pickup flash
@ -254,7 +255,8 @@ class AAmmo : public AInventory
{
DECLARE_CLASS_WITH_META(AAmmo, AInventory, PClassAmmo)
public:
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
AInventory *CreateCopy (AActor *other);
bool HandlePickup (AInventory *item);
PClassActor *GetParentAmmo () const;
@ -311,7 +313,8 @@ public:
bool bAltFire; // Set when this weapon's alternate fire is used.
virtual void MarkPrecacheSounds() const;
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual bool ShouldStay ();
virtual void AttachToOwner (AActor *other);
virtual bool HandlePickup (AInventory *item);
@ -395,7 +398,8 @@ class AWeaponGiver : public AWeapon
public:
bool TryPickup(AActor *&toucher);
void Serialize(FArchive &arc);
void Serialize(FSerializer &arc);
double DropAmmoFactor;
};
@ -431,7 +435,8 @@ class AHealthPickup : public AInventory
public:
int autousemode;
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual AInventory *CreateCopy (AActor *other);
virtual AInventory *CreateTossable ();
virtual bool HandlePickup (AInventory *item);
@ -451,7 +456,8 @@ class ABasicArmor : public AArmor
{
DECLARE_CLASS (ABasicArmor, AArmor)
public:
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual void Tick ();
virtual AInventory *CreateCopy (AActor *other);
virtual bool HandlePickup (AInventory *item);
@ -471,7 +477,8 @@ class ABasicArmorPickup : public AArmor
{
DECLARE_CLASS (ABasicArmorPickup, AArmor)
public:
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual AInventory *CreateCopy (AActor *other);
virtual bool Use (bool pickup);
@ -486,7 +493,8 @@ class ABasicArmorBonus : public AArmor
{
DECLARE_CLASS (ABasicArmorBonus, AArmor)
public:
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual AInventory *CreateCopy (AActor *other);
virtual bool Use (bool pickup);
@ -505,7 +513,8 @@ class AHexenArmor : public AArmor
{
DECLARE_CLASS (AHexenArmor, AArmor)
public:
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual AInventory *CreateCopy (AActor *other);
virtual AInventory *CreateTossable ();
virtual bool HandlePickup (AInventory *item);
@ -533,7 +542,7 @@ class APuzzleItem : public AInventory
{
DECLARE_CLASS_WITH_META(APuzzleItem, AInventory, PClassPuzzleItem)
public:
void Serialize (FArchive &arc);
bool ShouldStay ();
bool Use (bool pickup);
bool HandlePickup (AInventory *item);
@ -555,7 +564,8 @@ class ABackpackItem : public AInventory
{
DECLARE_CLASS (ABackpackItem, AInventory)
public:
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
bool HandlePickup (AInventory *item);
AInventory *CreateCopy (AActor *other);
AInventory *CreateTossable ();

View file

@ -7,7 +7,6 @@
#include "c_console.h"
#include "doomstat.h"
#include "v_font.h"
#include "farchive.h"
IMPLEMENT_CLASS(PClassPuzzleItem)
@ -20,12 +19,6 @@ void PClassPuzzleItem::DeriveData(PClass *newclass)
IMPLEMENT_CLASS(APuzzleItem)
void APuzzleItem::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << PuzzleItemNumber;
}
bool APuzzleItem::HandlePickup (AInventory *item)
{
// Can't carry more than 1 of each puzzle item in coop netplay

View file

@ -8,7 +8,7 @@
#include "s_sound.h"
#include "a_sharedglobal.h"
#include "statnums.h"
#include "farchive.h"
#include "serializer.h"
#include "d_player.h"
#include "r_utility.h"
@ -64,15 +64,23 @@ DEarthquake::DEarthquake(AActor *center, int intensityX, int intensityY, int int
//
//==========================================================================
void DEarthquake::Serialize (FArchive &arc)
void DEarthquake::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << m_Spot << m_Intensity << m_Countdown
<< m_TremorRadius << m_DamageRadius
<< m_QuakeSFX << m_Flags << m_CountdownStart
<< m_WaveSpeed
<< m_Falloff << m_Highpoint << m_MiniCount
<< m_RollIntensity << m_RollWave;
arc("spot", m_Spot)
("intensity", m_Intensity)
("countdown", m_Countdown)
("tremorradius", m_TremorRadius)
("damageradius", m_DamageRadius)
("quakesfx", m_QuakeSFX)
("quakeflags", m_Flags)
("countdownstart", m_CountdownStart)
("wavespeed", m_WaveSpeed)
("falloff", m_Falloff)
("highpoint", m_Highpoint)
("minicount", m_MiniCount)
("rollintensity", m_RollIntensity)
("rollwave", m_RollWave);
}
//==========================================================================

View file

@ -49,23 +49,27 @@ bool ASectorAction::IsActivatedByUse() const
void ASectorAction::Destroy ()
{
// Remove ourself from this sector's list of actions
AActor *probe = Sector->SecActTarget;
union
if (Sector != nullptr)
{
AActor **act;
ASectorAction **secact;
} prev;
prev.secact = &Sector->SecActTarget;
// Remove ourself from this sector's list of actions
AActor *probe = Sector->SecActTarget;
union
{
AActor **act;
ASectorAction **secact;
} prev;
prev.secact = &Sector->SecActTarget;
while (probe && probe != this)
{
prev.act = &probe->tracer;
probe = probe->tracer;
}
if (probe != NULL)
{
*prev.act = probe->tracer;
while (probe && probe != this)
{
prev.act = &probe->tracer;
probe = probe->tracer;
}
if (probe != nullptr)
{
*prev.act = probe->tracer;
}
Sector = nullptr;
}
Super::Destroy ();

View file

@ -24,7 +24,7 @@ public:
DBaseDecal (const AActor *actor);
DBaseDecal (const DBaseDecal *basis);
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Destroy ();
FTextureID StickToWall(side_t *wall, double x, double y, F3DFloor * ffloor);
double GetRealZ (const side_t *wall) const;
@ -33,9 +33,7 @@ public:
void Spread (const FDecalTemplate *tpl, side_t *wall, double x, double y, double z, F3DFloor * ffloor);
void GetXY (side_t *side, double &x, double &y) const;
static void SerializeChain (FArchive &arc, DBaseDecal **firstptr);
DBaseDecal *WallNext, **WallPrev;
DBaseDecal *WallNext, *WallPrev;
double LeftDistance;
double Z;
@ -46,7 +44,8 @@ public:
FTextureID PicNum;
DWORD RenderFlags;
FRenderStyle RenderStyle;
sector_t * Sector; // required for 3D floors
side_t *Side;
sector_t *Sector;
protected:
virtual DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const;
@ -70,9 +69,6 @@ public:
void BeginPlay ();
void Destroy ();
void Serialize (FArchive &arc);
static void SerializeTime (FArchive &arc);
protected:
DBaseDecal *CloneSelf(const FDecalTemplate *tpl, double x, double y, double z, side_t *wall, F3DFloor * ffloor) const;
static void CheckMax ();
@ -122,7 +118,7 @@ public:
float r2, float g2, float b2, float a2,
float time, AActor *who);
void Destroy ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
AActor *WhoFor() { return ForWho; }
void Cancel ();
@ -165,7 +161,7 @@ public:
int damrad, int tremrad, FSoundID quakesfx, int flags,
double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, double rollIntensity, double rollWave);
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
TObjPtr<AActor> m_Spot;
double m_TremorRadius, m_DamageRadius;
@ -194,7 +190,8 @@ class AMorphProjectile : public AActor
DECLARE_CLASS (AMorphProjectile, AActor)
public:
int DoSpecialDamage (AActor *target, int damage, FName damagetype);
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
FNameNoInit PlayerClass, MonsterClass, MorphFlash, UnMorphFlash;
int Duration, MorphStyle;
@ -206,7 +203,8 @@ class AMorphedMonster : public AActor
HAS_OBJECT_POINTERS
public:
void Tick ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Die (AActor *source, AActor *inflictor, int dmgflags);
void Destroy ();

View file

@ -36,8 +36,8 @@
#include "a_sharedglobal.h"
#include "p_local.h"
#include "p_lnspec.h"
#include "farchive.h"
#include "r_sky.h"
#include "r_state.h"
#include "portal.h"
// arg0 = Visibility*4 for this skybox
@ -170,7 +170,10 @@ void ASectorSilencer::BeginPlay ()
void ASectorSilencer::Destroy ()
{
Sector->Flags &= ~SECF_SILENT;
if (Sector != nullptr)
{
Sector->Flags &= ~SECF_SILENT;
}
Super::Destroy ();
}

View file

@ -59,7 +59,7 @@ void ASoundEnvironment::PostBeginPlay ()
void ASoundEnvironment::Activate (AActor *activator)
{
zones[Sector->ZoneNumber].Environment = S_FindEnvironment ((args[0]<<8) | (args[1]));
Zones[Sector->ZoneNumber].Environment = S_FindEnvironment ((args[0]<<8) | (args[1]));
}
// Deactivate just exists so that you can flag the thing as dormant in an editor

View file

@ -65,7 +65,7 @@
#include "s_sound.h"
#include "m_random.h"
#include "s_sndseq.h"
#include "farchive.h"
#include "serializer.h"
// SoundSequenceSlot --------------------------------------------------------
@ -74,7 +74,8 @@ class ASoundSequenceSlot : public AActor
DECLARE_CLASS (ASoundSequenceSlot, AActor)
HAS_OBJECT_POINTERS
public:
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
TObjPtr<DSeqNode> Sequence;
};
@ -89,10 +90,10 @@ END_POINTERS
//
//==========================================================================
void ASoundSequenceSlot::Serialize (FArchive &arc)
void ASoundSequenceSlot::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << Sequence;
arc("sequence", Sequence);
}
// SoundSequence ------------------------------------------------------------

View file

@ -39,7 +39,7 @@
#include "i_system.h"
#include "thingdef/thingdef.h"
#include "doomstat.h"
#include "farchive.h"
#include "serializer.h"
#include "a_pickups.h"
static FRandom pr_spot ("SpecialSpot");
@ -58,7 +58,7 @@ TObjPtr<DSpotState> DSpotState::SpotState;
struct FSpotList
{
const PClass *Type;
PClassActor *Type;
TArray<ASpecialSpot*> Spots;
unsigned Index;
int SkipCount;
@ -68,7 +68,7 @@ struct FSpotList
{
}
FSpotList(const PClass *type)
FSpotList(PClassActor *type)
{
Type = type;
Index = 0;
@ -82,17 +82,6 @@ struct FSpotList
//
//----------------------------------------------------------------------------
void Serialize(FArchive &arc)
{
arc << Type << Spots << Index << SkipCount << numcalls;
}
//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------
bool Add(ASpecialSpot *newspot)
{
for(unsigned i = 0; i < Spots.Size(); i++)
@ -194,6 +183,26 @@ struct FSpotList
//
//----------------------------------------------------------------------------
FSerializer &Serialize(FSerializer &arc, const char *key, FSpotList &list, FSpotList *def)
{
if (arc.BeginObject(key))
{
arc("type", list.Type)
("spots", list.Spots)
("index", list.Index)
("skipcount", list.SkipCount)
("numcalls", list.numcalls)
.EndObject();
}
return arc;
}
//----------------------------------------------------------------------------
//
//
//
//----------------------------------------------------------------------------
DSpotState::DSpotState ()
: DThinker (STAT_INFO)
{
@ -215,10 +224,6 @@ DSpotState::DSpotState ()
void DSpotState::Destroy ()
{
for(unsigned i = 0; i < SpotLists.Size(); i++)
{
delete SpotLists[i];
}
SpotLists.Clear();
SpotLists.ShrinkToFit();
@ -254,13 +259,13 @@ DSpotState *DSpotState::GetSpotState(bool create)
//
//----------------------------------------------------------------------------
FSpotList *DSpotState::FindSpotList(const PClass *type)
FSpotList *DSpotState::FindSpotList(PClassActor *type)
{
for(unsigned i = 0; i < SpotLists.Size(); i++)
{
if (SpotLists[i]->Type == type) return SpotLists[i];
if (SpotLists[i].Type == type) return &SpotLists[i];
}
return SpotLists[SpotLists.Push(new FSpotList(type))];
return &SpotLists[SpotLists.Push(FSpotList(type))];
}
//----------------------------------------------------------------------------
@ -295,27 +300,10 @@ bool DSpotState::RemoveSpot(ASpecialSpot *spot)
//
//----------------------------------------------------------------------------
void DSpotState::Serialize(FArchive &arc)
void DSpotState::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
if (arc.IsStoring())
{
arc.WriteCount(SpotLists.Size());
for(unsigned i = 0; i < SpotLists.Size(); i++)
{
SpotLists[i]->Serialize(arc);
}
}
else
{
unsigned c = arc.ReadCount();
SpotLists.Resize(c);
for(unsigned i = 0; i < SpotLists.Size(); i++)
{
SpotLists[i] = new FSpotList;
SpotLists[i]->Serialize(arc);
}
}
arc("spots", SpotLists);
}
//----------------------------------------------------------------------------
@ -324,7 +312,7 @@ void DSpotState::Serialize(FArchive &arc)
//
//----------------------------------------------------------------------------
ASpecialSpot *DSpotState::GetNextInList(const PClass *type, int skipcounter)
ASpecialSpot *DSpotState::GetNextInList(PClassActor *type, int skipcounter)
{
FSpotList *list = FindSpotList(type);
if (list != NULL) return list->GetNextInList(skipcounter);
@ -337,7 +325,7 @@ ASpecialSpot *DSpotState::GetNextInList(const PClass *type, int skipcounter)
//
//----------------------------------------------------------------------------
ASpecialSpot *DSpotState::GetSpotWithMinMaxDistance(const PClass *type, double x, double y, double mindist, double maxdist)
ASpecialSpot *DSpotState::GetSpotWithMinMaxDistance(PClassActor *type, double x, double y, double mindist, double maxdist)
{
FSpotList *list = FindSpotList(type);
if (list != NULL) return list->GetSpotWithMinMaxDistance(x, y, mindist, maxdist);
@ -350,7 +338,7 @@ ASpecialSpot *DSpotState::GetSpotWithMinMaxDistance(const PClass *type, double x
//
//----------------------------------------------------------------------------
ASpecialSpot *DSpotState::GetRandomSpot(const PClass *type, bool onlyonce)
ASpecialSpot *DSpotState::GetRandomSpot(PClassActor *type, bool onlyonce)
{
FSpotList *list = FindSpotList(type);
if (list != NULL) return list->GetRandomSpot(onlyonce);

View file

@ -22,7 +22,7 @@ class DSpotState : public DThinker
{
DECLARE_CLASS(DSpotState, DThinker)
static TObjPtr<DSpotState> SpotState;
TArray<FSpotList *> SpotLists;
TArray<FSpotList> SpotLists;
public:
@ -31,13 +31,13 @@ public:
void Destroy ();
void Tick ();
static DSpotState *GetSpotState(bool create = true);
FSpotList *FindSpotList(const PClass *type);
FSpotList *FindSpotList(PClassActor *type);
bool AddSpot(ASpecialSpot *spot);
bool RemoveSpot(ASpecialSpot *spot);
void Serialize(FArchive &arc);
ASpecialSpot *GetNextInList(const PClass *type, int skipcounter);
ASpecialSpot *GetSpotWithMinMaxDistance(const PClass *type, double x, double y, double mindist, double maxdist);
ASpecialSpot *GetRandomSpot(const PClass *type, bool onlyonce = false);
void Serialize(FSerializer &arc);
ASpecialSpot *GetNextInList(PClassActor *type, int skipcounter);
ASpecialSpot *GetSpotWithMinMaxDistance(PClassActor *type, double x, double y, double mindist, double maxdist);
ASpecialSpot *GetRandomSpot(PClassActor *type, bool onlyonce = false);
};

View file

@ -1,7 +1,7 @@
#include "a_pickups.h"
#include "a_weaponpiece.h"
#include "doomstat.h"
#include "farchive.h"
#include "serializer.h"
IMPLEMENT_CLASS(PClassWeaponPiece)
IMPLEMENT_CLASS (AWeaponHolder)
@ -17,10 +17,11 @@ void PClassWeaponPiece::ReplaceClassRef(PClass *oldclass, PClass *newclass)
}
void AWeaponHolder::Serialize (FArchive &arc)
void AWeaponHolder::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc << PieceMask << PieceWeapon;
arc("piecemask", PieceMask)
("pieceweapon", PieceWeapon);
}
@ -29,10 +30,13 @@ IMPLEMENT_POINTY_CLASS (AWeaponPiece)
END_POINTERS
void AWeaponPiece::Serialize (FArchive &arc)
void AWeaponPiece::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << WeaponClass << FullWeapon << PieceValue;
auto def = (AWeaponPiece*)GetDefault();
arc("weaponclass", WeaponClass, def->WeaponClass)
("fullweapon", FullWeapon)
("piecevalue", PieceValue, def->PieceValue);
}
//==========================================================================

View file

@ -15,7 +15,8 @@ class AWeaponPiece : public AInventory
protected:
bool PrivateShouldStay ();
public:
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
bool TryPickup (AActor *&toucher);
bool TryPickupRestricted (AActor *&toucher);
bool ShouldStay ();
@ -23,7 +24,7 @@ public:
virtual void PlayPickupSound (AActor *toucher);
int PieceValue;
PClassWeapon *WeaponClass;
PClassActor *WeaponClass;
TObjPtr<AWeapon> FullWeapon;
};
@ -35,7 +36,8 @@ class AWeaponHolder : public AInventory
public:
int PieceMask;
const PClass * PieceWeapon;
PClassActor * PieceWeapon;
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
};

View file

@ -17,7 +17,7 @@
#include "doomstat.h"
#include "g_level.h"
#include "d_net.h"
#include "farchive.h"
#include "serializer.h"
#define BONUSADD 6
@ -73,28 +73,45 @@ void PClassWeapon::ReplaceClassRef(PClass *oldclass, PClass *newclass)
//
//===========================================================================
void AWeapon::Serialize (FArchive &arc)
void AWeapon::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << WeaponFlags
<< AmmoType1 << AmmoType2
<< AmmoGive1 << AmmoGive2
<< MinAmmo1 << MinAmmo2
<< AmmoUse1 << AmmoUse2
<< Kickback
<< YAdjust
<< UpSound << ReadySound
<< SisterWeaponType
<< ProjectileType << AltProjectileType
<< SelectionOrder
<< MoveCombatDist
<< Ammo1 << Ammo2 << SisterWeapon << GivenAsMorphWeapon
<< bAltFire
<< ReloadCounter
<< BobStyle << BobSpeed << BobRangeX << BobRangeY
<< FOVScale
<< Crosshair
<< MinSelAmmo1 << MinSelAmmo2;
auto def = (AWeapon*)GetDefault();
arc("weaponflags", WeaponFlags, def->WeaponFlags)
("ammogive1", AmmoGive1, def->AmmoGive1)
("ammogive2", AmmoGive2, def->AmmoGive2)
("minammo1", MinAmmo1, def->MinAmmo1)
("minammo2", MinAmmo2, def->MinAmmo2)
("ammouse1", AmmoUse1, def->AmmoUse1)
("ammouse2", AmmoUse2, def->AmmoUse2)
("kickback", Kickback, Kickback)
("yadjust", YAdjust, def->YAdjust)
("upsound", UpSound, def->UpSound)
("readysound", ReadySound, def->ReadySound)
("selectionorder", SelectionOrder, def->SelectionOrder)
("ammo1", Ammo1)
("ammo2", Ammo2)
("sisterweapon", SisterWeapon)
("givenasmorphweapon", GivenAsMorphWeapon, def->GivenAsMorphWeapon)
("altfire", bAltFire, def->bAltFire)
("reloadcounter", ReloadCounter, def->ReloadCounter)
("bobstyle", BobStyle, def->BobStyle)
("bobspeed", BobSpeed, def->BobSpeed)
("bobrangex", BobRangeX, def->BobRangeX)
("bobrangey", BobRangeY, def->BobRangeY)
("fovscale", FOVScale, def->FOVScale)
("crosshair", Crosshair, def->Crosshair)
("minselammo1", MinSelAmmo1, def->MinSelAmmo1)
("minselammo2", MinSelAmmo2, def->MinSelAmmo2);
/* these can never change
("ammotype1", AmmoType1, def->AmmoType1)
("ammotype2", AmmoType2, def->AmmoType2)
("sisterweapontype", SisterWeaponType, def->SisterWeaponType)
("projectiletype", ProjectileType, def->ProjectileType)
("altprojectiletype", AltProjectileType, def->AltProjectileType)
("movecombatdist", MoveCombatDist, def->MoveCombatDist)
*/
}
//===========================================================================
@ -741,10 +758,11 @@ FState *AWeapon::GetStateForButtonName (FName button)
IMPLEMENT_CLASS(AWeaponGiver)
void AWeaponGiver::Serialize(FArchive &arc)
void AWeaponGiver::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc << DropAmmoFactor;
auto def = (AWeaponGiver *)GetDefault();
arc("dropammofactor", DropAmmoFactor, def->DropAmmoFactor);
}
bool AWeaponGiver::TryPickup(AActor *&toucher)

View file

@ -39,7 +39,7 @@
#include "v_video.h"
#include "cmdlib.h"
#include "doomstat.h"
#include "farchive.h"
#include "serializer.h"
EXTERN_CVAR(Int, con_scaletext)
int active_con_scaletext();
@ -56,14 +56,6 @@ IMPLEMENT_CLASS (DHUDMessageTypeOnFadeOut)
* Basic HUD message. Appears and disappears without any special effects *
*************************************************************************/
inline FArchive &operator<< (FArchive &arc, EColorRange &i)
{
BYTE val = (BYTE)i;
arc << val;
i = (EColorRange)val;
return arc;
}
//============================================================================
//
// DHUDMessage Constructor
@ -180,20 +172,34 @@ DHUDMessage::~DHUDMessage ()
//
//============================================================================
void DHUDMessage::Serialize(FArchive &arc)
void DHUDMessage::Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc << Left << Top << CenterX << HoldTics
<< Tics << State << TextColor
<< SBarID << SourceText << Font << Next
<< HUDWidth << HUDHeight
<< NoWrap
<< ClipX << ClipY << ClipWidth << ClipHeight
<< WrapWidth
<< HandleAspect
<< VisibilityFlags
<< Style << Alpha;
if (arc.IsLoading())
arc("left", Left)
("top", Top)
("centerx", CenterX)
("holdtics", HoldTics)
("tics", Tics)
("state", State)
.Enum("textcolor", TextColor)
("sbarid", SBarID)
("sourcetext", SourceText)
("font", Font)
("next", Next)
("hudwidth", HUDWidth)
("hudheight", HUDHeight)
("nowrap", NoWrap)
("clipx", ClipX)
("clipy", ClipY)
("clipwidth", ClipWidth)
("clipheight", ClipHeight)
("wrapwidth", WrapWidth)
("handleaspect", HandleAspect)
("visibilityflags", VisibilityFlags)
("style", Style)
("alpha", Alpha);
if (arc.isReading())
{
Lines = NULL;
ResetText(SourceText);
@ -504,10 +510,10 @@ DHUDMessageFadeOut::DHUDMessageFadeOut (FFont *font, const char *text, float x,
//
//============================================================================
void DHUDMessageFadeOut::Serialize (FArchive &arc)
void DHUDMessageFadeOut::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << FadeOutTics;
arc("fadeouttics", FadeOutTics);
}
//============================================================================
@ -609,10 +615,10 @@ DHUDMessageFadeInOut::DHUDMessageFadeInOut (FFont *font, const char *text, float
//
//============================================================================
void DHUDMessageFadeInOut::Serialize (FArchive &arc)
void DHUDMessageFadeInOut::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << FadeInTics;
arc("fadeintics", FadeInTics);
}
//============================================================================
@ -718,10 +724,13 @@ DHUDMessageTypeOnFadeOut::DHUDMessageTypeOnFadeOut (FFont *font, const char *tex
//
//============================================================================
void DHUDMessageTypeOnFadeOut::Serialize (FArchive &arc)
void DHUDMessageTypeOnFadeOut::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << TypeOnTime << CurrLine << LineVisible << LineLen;
arc("typeontime", TypeOnTime)
("currline", CurrLine)
("linevisible", LineVisible)
("linelen", LineLen);
}
//============================================================================

View file

@ -71,7 +71,7 @@ public:
EColorRange textColor, float holdTime);
virtual ~DHUDMessage ();
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
void Draw (int bottom, int visibility);
virtual void ResetText (const char *text);
@ -157,7 +157,7 @@ public:
DHUDMessageFadeOut (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
EColorRange textColor, float holdTime, float fadeOutTime);
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual void DoDraw (int linenum, int x, int y, bool clean, int hudheight);
virtual bool Tick ();
@ -176,7 +176,7 @@ public:
DHUDMessageFadeInOut (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
EColorRange textColor, float holdTime, float fadeInTime, float fadeOutTime);
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual void DoDraw (int linenum, int x, int y, bool clean, int hudheight);
virtual bool Tick ();
@ -195,7 +195,7 @@ public:
DHUDMessageTypeOnFadeOut (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
EColorRange textColor, float typeTime, float holdTime, float fadeOutTime);
virtual void Serialize (FArchive &arc);
virtual void Serialize(FSerializer &arc);
virtual void DoDraw (int linenum, int x, int y, bool clean, int hudheight);
virtual bool Tick ();
virtual void ScreenSizeChanged ();
@ -355,7 +355,8 @@ public:
static void AddBlend (float r, float g, float b, float a, float v_blend[4]);
virtual void Serialize (FArchive &arc);
// do not make this a DObject Serialize function because it's not used like one!
void SerializeMessages(FSerializer &arc);
virtual void Tick ();
virtual void Draw (EHudState state);

View file

@ -51,8 +51,9 @@
#include "colormatcher.h"
#include "v_palette.h"
#include "d_player.h"
#include "farchive.h"
#include "serializer.h"
#include "gstrings.h"
#include "r_utility.h"
#include "../version.h"
@ -1654,12 +1655,9 @@ void DBaseStatusBar::ReceivedWeapon (AWeapon *weapon)
{
}
void DBaseStatusBar::Serialize (FArchive &arc)
void DBaseStatusBar::SerializeMessages(FSerializer &arc)
{
for (size_t i = 0; i < countof(Messages); ++i)
{
arc << Messages[i];
}
arc.Array("hudmessages", Messages, 3, true);
}
void DBaseStatusBar::ScreenSizeChanged ()

View file

@ -55,7 +55,8 @@ class ASigil : public AWeapon
public:
bool HandlePickup (AInventory *item);
AInventory *CreateCopy (AActor *other);
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
bool SpecialDropAction (AActor *dropper);
static int GiveSigilPiece (AActor *daPlayer);
void BeginPlay();

View file

@ -18,7 +18,7 @@
#include "templates.h"
#include "d_event.h"
#include "v_font.h"
#include "farchive.h"
#include "serializer.h"
#include "p_spec.h"
#include "portal.h"

View file

@ -753,10 +753,11 @@ void ASigil::BeginPlay()
//
//============================================================================
void ASigil::Serialize (FArchive &arc)
void ASigil::Serialize(FSerializer &arc)
{
Super::Serialize (arc);
arc << NumPieces << DownPieces;
arc("numpieces", NumPieces)
("downpieces", DownPieces);
}
//============================================================================

View file

@ -375,6 +375,9 @@ void PClassActor::InitializeNativeDefaults()
else
{
memset (Defaults, 0, Size);
// Non-DECORATE properties that must be set.
((AActor*)Defaults)->DamageMultiply = 1.; // fixme: Make this a DECORATE property.
((AActor*)Defaults)->ConversationRoot = -1;
}
}

View file

@ -52,7 +52,6 @@
struct Baggage;
class FScanner;
struct FActorInfo;
class FArchive;
class FIntCVar;
enum EStateType
@ -168,10 +167,6 @@ struct FStateLabels
void Destroy(); // intentionally not a destructor!
};
FArchive &operator<< (FArchive &arc, FState *&state);
#include "gametype.h"
struct DmgFactors : public TMap<FName, double>

View file

@ -45,7 +45,7 @@
#include "d_net.h"
#include "d_dehacked.h"
#include "gi.h"
#include "farchive.h"
#include "serializer.h"
#include "r_utility.h"
#include "a_morph.h"
@ -1026,10 +1026,10 @@ public:
}
// You'll probably never be able to catch this in a save game, but
// just in case, add a proper serializer.
void Serialize(FArchive &arc)
void Serialize(FSerializer &arc)
{
Super::Serialize(arc);
arc << Pawn;
arc("pawn", Pawn);
}
};

View file

@ -449,10 +449,15 @@ struct pcx_t
};
inline void putc(unsigned char chr, FileWriter *file)
{
file->Write(&chr, 1);
}
//
// WritePCXfile
//
void WritePCXfile (FILE *file, const BYTE *buffer, const PalEntry *palette,
void WritePCXfile (FileWriter *file, const BYTE *buffer, const PalEntry *palette,
ESSType color_type, int width, int height, int pitch)
{
BYTE temprow[MAXWIDTH * 3];
@ -480,7 +485,7 @@ void WritePCXfile (FILE *file, const BYTE *buffer, const PalEntry *palette,
pcx.palette_type = 1; // not a grey scale
memset (pcx.filler, 0, sizeof(pcx.filler));
fwrite (&pcx, 128, 1, file);
file->Write(&pcx, 128);
bytes_per_row_minus_one = ((color_type == SS_PAL) ? width : width * 3) - 1;
@ -593,7 +598,7 @@ void WritePCXfile (FILE *file, const BYTE *buffer, const PalEntry *palette,
//
// WritePNGfile
//
void WritePNGfile (FILE *file, const BYTE *buffer, const PalEntry *palette,
void WritePNGfile (FileWriter *file, const BYTE *buffer, const PalEntry *palette,
ESSType color_type, int width, int height, int pitch)
{
char software[100];
@ -655,7 +660,7 @@ static bool FindFreeName (FString &fullname, const char *extension)
void M_ScreenShot (const char *filename)
{
FILE *file;
FileWriter *file;
FString autoname;
bool writepcx = (stricmp (screenshot_type, "pcx") == 0); // PNG is the default
@ -709,7 +714,7 @@ void M_ScreenShot (const char *filename)
{
screen->GetFlashedPalette(palette);
}
file = fopen (autoname, "wb");
file = FileWriter::Open(autoname);
if (file == NULL)
{
Printf ("Could not open %s\n", autoname.GetChars());
@ -726,7 +731,7 @@ void M_ScreenShot (const char *filename)
WritePNGfile(file, buffer, palette, color_type,
screen->GetWidth(), screen->GetHeight(), pitch);
}
fclose(file);
delete file;
screen->ReleaseScreenshotBuffer();
if (!screenshot_quiet)

View file

@ -80,7 +80,7 @@ PNGHandle::PNGHandle (FILE *file) : File(0), bDeleteFilePtr(true), ChunkPt(0)
File = new FileReader(file);
}
PNGHandle::PNGHandle (FileReader *file) : File(file), bDeleteFilePtr(false), ChunkPt(0) {}
PNGHandle::PNGHandle (FileReader *file, bool takereader) : File(file), bDeleteFilePtr(takereader), ChunkPt(0) {}
PNGHandle::~PNGHandle ()
{
for (unsigned int i = 0; i < TextChunks.Size(); ++i)
@ -101,7 +101,7 @@ PNGHandle::~PNGHandle ()
static inline void MakeChunk (void *where, DWORD type, size_t len);
static inline void StuffPalette (const PalEntry *from, BYTE *to);
static bool WriteIDAT (FILE *file, const BYTE *data, int len);
static bool WriteIDAT (FileWriter *file, const BYTE *data, int len);
static void UnfilterRow (int width, BYTE *dest, BYTE *stream, BYTE *prev, int bpp);
static void UnpackPixels (int width, int bytesPerRow, int bitdepth, const BYTE *rowin, BYTE *rowout, bool grayscale);
@ -131,7 +131,7 @@ CVAR(Float, png_gamma, 0.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
//
//==========================================================================
bool M_CreatePNG (FILE *file, const BYTE *buffer, const PalEntry *palette,
bool M_CreatePNG (FileWriter *file, const BYTE *buffer, const PalEntry *palette,
ESSType color_type, int width, int height, int pitch)
{
BYTE work[8 + // signature
@ -171,7 +171,7 @@ bool M_CreatePNG (FILE *file, const BYTE *buffer, const PalEntry *palette,
work_len = sizeof(work) - (12+256*3);
}
if (fwrite (work, 1, work_len, file) != work_len)
if (file->Write (work, work_len) != work_len)
return false;
return M_SaveBitmap (buffer, color_type, width, height, pitch, file);
@ -185,7 +185,7 @@ bool M_CreatePNG (FILE *file, const BYTE *buffer, const PalEntry *palette,
//
//==========================================================================
bool M_CreateDummyPNG (FILE *file)
bool M_CreateDummyPNG (FileWriter *file)
{
static const BYTE dummyPNG[] =
{
@ -195,7 +195,7 @@ bool M_CreateDummyPNG (FILE *file)
0,0,0,10,'I','D','A','T',
104,222,99,96,0,0,0,2,0,1,0x9f,0x65,0x0e,0x18
};
return fwrite (dummyPNG, 1, sizeof(dummyPNG), file) == sizeof(dummyPNG);
return file->Write (dummyPNG, sizeof(dummyPNG)) == sizeof(dummyPNG);
}
@ -207,10 +207,10 @@ bool M_CreateDummyPNG (FILE *file)
//
//==========================================================================
bool M_FinishPNG (FILE *file)
bool M_FinishPNG (FileWriter *file)
{
static const BYTE iend[12] = { 0,0,0,0,73,69,78,68,174,66,96,130 };
return fwrite (iend, 1, 12, file) == 12;
return file->Write (iend, 12) == 12;
}
//==========================================================================
@ -221,13 +221,13 @@ bool M_FinishPNG (FILE *file)
//
//==========================================================================
bool M_AppendPNGChunk (FILE *file, DWORD chunkID, const BYTE *chunkData, DWORD len)
bool M_AppendPNGChunk (FileWriter *file, DWORD chunkID, const BYTE *chunkData, DWORD len)
{
DWORD head[2] = { BigLong((unsigned int)len), chunkID };
DWORD crc;
if (fwrite (head, 1, 8, file) == 8 &&
(len == 0 || fwrite (chunkData, 1, len, file) == len))
if (file->Write (head, 8) == 8 &&
(len == 0 || file->Write (chunkData, len) == len))
{
crc = CalcCRC32 ((BYTE *)&head[1], 4);
if (len != 0)
@ -235,7 +235,7 @@ bool M_AppendPNGChunk (FILE *file, DWORD chunkID, const BYTE *chunkData, DWORD l
crc = AddCRC32 (crc, chunkData, len);
}
crc = BigLong((unsigned int)crc);
return fwrite (&crc, 1, 4, file) == 4;
return file->Write (&crc, 4) == 4;
}
return false;
}
@ -248,7 +248,7 @@ bool M_AppendPNGChunk (FILE *file, DWORD chunkID, const BYTE *chunkData, DWORD l
//
//==========================================================================
bool M_AppendPNGText (FILE *file, const char *keyword, const char *text)
bool M_AppendPNGText (FileWriter *file, const char *keyword, const char *text)
{
struct { DWORD len, id; char key[80]; } head;
int len = (int)strlen (text);
@ -261,8 +261,8 @@ bool M_AppendPNGText (FILE *file, const char *keyword, const char *text)
strncpy (head.key, keyword, keylen);
head.key[keylen] = 0;
if ((int)fwrite (&head, 1, keylen + 9, file) == keylen + 9 &&
(int)fwrite (text, 1, len, file) == len)
if ((int)file->Write (&head, keylen + 9) == keylen + 9 &&
(int)file->Write (text, len) == len)
{
crc = CalcCRC32 ((BYTE *)&head+4, keylen + 5);
if (len != 0)
@ -270,7 +270,7 @@ bool M_AppendPNGText (FILE *file, const char *keyword, const char *text)
crc = AddCRC32 (crc, (BYTE *)text, len);
}
crc = BigLong((unsigned int)crc);
return fwrite (&crc, 1, 4, file) == 4;
return file->Write (&crc, 4) == 4;
}
return false;
}
@ -374,15 +374,14 @@ bool M_GetPNGText (PNGHandle *png, const char *keyword, char *buffer, size_t buf
//
//==========================================================================
PNGHandle *M_VerifyPNG (FILE *file)
PNGHandle *M_VerifyPNG (FileReader *filer, bool takereader)
{
PNGHandle::Chunk chunk;
FileReader *filer;
PNGHandle *png;
DWORD data[2];
bool sawIDAT = false;
if (fread (&data, 1, 8, file) != 8)
if (filer->Read(&data, 8) != 8)
{
return NULL;
}
@ -390,7 +389,7 @@ PNGHandle *M_VerifyPNG (FILE *file)
{ // Does not have PNG signature
return NULL;
}
if (fread (&data, 1, 8, file) != 8)
if (filer->Read (&data, 8) != 8)
{
return NULL;
}
@ -400,8 +399,7 @@ PNGHandle *M_VerifyPNG (FILE *file)
}
// It looks like a PNG so far, so start creating a PNGHandle for it
png = new PNGHandle (file);
filer = png->File;
png = new PNGHandle (filer, takereader);
chunk.ID = data[1];
chunk.Offset = 16;
chunk.Size = BigLong((unsigned int)data[0]);
@ -430,7 +428,7 @@ PNGHandle *M_VerifyPNG (FILE *file)
sawIDAT = true;
}
chunk.ID = data[1];
chunk.Offset = ftell (file);
chunk.Offset = filer->Tell();
chunk.Size = BigLong((unsigned int)data[0]);
png->Chunks.Push (chunk);
@ -454,6 +452,12 @@ PNGHandle *M_VerifyPNG (FILE *file)
return NULL;
}
PNGHandle *M_VerifyPNG(FILE *file)
{
FileReader *fr = new FileReader(file);
return M_VerifyPNG(fr, true);
}
//==========================================================================
//
// M_FreePNG
@ -900,7 +904,7 @@ static int SelectFilter(Byte row[5][1 + MAXWIDTH*3], Byte prior[MAXWIDTH*3], int
//
//==========================================================================
bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, int pitch, FILE *file)
bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, int pitch, FileWriter *file)
{
#if USE_FILTER_HEURISTIC
Byte prior[MAXWIDTH*3];
@ -1040,7 +1044,7 @@ bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, i
//
//==========================================================================
static bool WriteIDAT (FILE *file, const BYTE *data, int len)
static bool WriteIDAT (FileWriter *file, const BYTE *data, int len)
{
DWORD foo[2], crc;
@ -1049,9 +1053,9 @@ static bool WriteIDAT (FILE *file, const BYTE *data, int len)
crc = CalcCRC32 ((BYTE *)&foo[1], 4);
crc = BigLong ((unsigned int)AddCRC32 (crc, data, len));
if (fwrite (foo, 1, 8, file) != 8 ||
fwrite (data, 1, len, file) != (size_t)len ||
fwrite (&crc, 1, 4, file) != 4)
if (file->Write (foo, 8) != 8 ||
file->Write (data, len) != (size_t)len ||
file->Write (&crc, 4) != 4)
{
return false;
}

View file

@ -36,6 +36,7 @@
#include <stdio.h>
#include "doomtype.h"
#include "v_video.h"
#include "files.h"
// PNG Writing --------------------------------------------------------------
@ -43,22 +44,22 @@
// The passed file should be a newly created file.
// This function writes the PNG signature and the IHDR, gAMA, PLTE, and IDAT
// chunks.
bool M_CreatePNG (FILE *file, const BYTE *buffer, const PalEntry *pal,
bool M_CreatePNG (FileWriter *file, const BYTE *buffer, const PalEntry *pal,
ESSType color_type, int width, int height, int pitch);
// Creates a grayscale 1x1 PNG file. Used for savegames without savepics.
bool M_CreateDummyPNG (FILE *file);
bool M_CreateDummyPNG (FileWriter *file);
// Appends any chunk to a PNG file started with M_CreatePNG.
bool M_AppendPNGChunk (FILE *file, DWORD chunkID, const BYTE *chunkData, DWORD len);
bool M_AppendPNGChunk (FileWriter *file, DWORD chunkID, const BYTE *chunkData, DWORD len);
// Adds a tEXt chunk to a PNG file started with M_CreatePNG.
bool M_AppendPNGText (FILE *file, const char *keyword, const char *text);
bool M_AppendPNGText (FileWriter *file, const char *keyword, const char *text);
// Appends the IEND chunk to a PNG file.
bool M_FinishPNG (FILE *file);
bool M_FinishPNG (FileWriter *file);
bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, int pitch, FILE *file);
bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, int pitch, FileWriter *file);
// PNG Reading --------------------------------------------------------------
@ -79,7 +80,7 @@ struct PNGHandle
unsigned int ChunkPt;
PNGHandle(FILE *file);
PNGHandle(FileReader *file);
PNGHandle(FileReader *file, bool takereader = false);
~PNGHandle();
};
@ -87,7 +88,7 @@ struct PNGHandle
// the signature, but also checking for the IEND chunk. CRC checking of
// each chunk is not done. If it is valid, you get a PNGHandle to pass to
// the following functions.
PNGHandle *M_VerifyPNG (FileReader *file);
PNGHandle *M_VerifyPNG (FileReader *file, bool takereader = false);
PNGHandle *M_VerifyPNG (FILE *file);
// Finds a chunk in a PNG file. The file pointer will be positioned at the

View file

@ -61,7 +61,7 @@
#include "doomstat.h"
#include "m_random.h"
#include "farchive.h"
#include "serializer.h"
#include "b_bot.h"
#include "m_png.h"
#include "m_crc32.h"
@ -291,24 +291,29 @@ DWORD FRandom::StaticSumSeeds ()
//
//==========================================================================
void FRandom::StaticWriteRNGState (FILE *file)
void FRandom::StaticWriteRNGState (FSerializer &arc)
{
FRandom *rng;
FPNGChunkArchive arc (file, RAND_ID);
arc << rngseed;
arc("rngseed", rngseed);
for (rng = FRandom::RNGList; rng != NULL; rng = rng->Next)
if (arc.BeginArray("rngs"))
{
// Only write those RNGs that have names
if (rng->NameCRC != 0)
for (rng = FRandom::RNGList; rng != NULL; rng = rng->Next)
{
arc << rng->NameCRC << rng->idx;
for (int i = 0; i < SFMT::N32; ++i)
// Only write those RNGs that have names
if (rng->NameCRC != 0)
{
arc << rng->sfmt.u[i];
if (arc.BeginObject(nullptr))
{
arc("crc", rng->NameCRC)
("index", rng->idx)
.Array("u", rng->sfmt.u, SFMT::N32)
.EndObject();
}
}
}
arc.EndArray();
}
}
@ -321,51 +326,35 @@ void FRandom::StaticWriteRNGState (FILE *file)
//
//==========================================================================
void FRandom::StaticReadRNGState (PNGHandle *png)
void FRandom::StaticReadRNGState(FSerializer &arc)
{
FRandom *rng;
size_t len = M_FindPNGChunk (png, RAND_ID);
if (len != 0)
arc("rngseed", rngseed);
if (arc.BeginArray("rngs"))
{
const size_t sizeof_rng = sizeof(rng->NameCRC) + sizeof(rng->idx) + sizeof(rng->sfmt.u);
const int rngcount = (int)((len-4) / sizeof_rng);
int i;
DWORD crc;
int count = arc.ArraySize();
FPNGChunkArchive arc (png->File->GetFile(), RAND_ID, len);
arc << rngseed;
FRandom::StaticClearRandom ();
for (i = rngcount; i; --i)
for (int i = 0; i < count; i++)
{
arc << crc;
for (rng = FRandom::RNGList; rng != NULL; rng = rng->Next)
if (arc.BeginObject(nullptr))
{
if (rng->NameCRC == crc)
uint32_t crc;
arc("crc", crc);
for (rng = FRandom::RNGList; rng != NULL; rng = rng->Next)
{
arc << rng->idx;
for (int i = 0; i < SFMT::N32; ++i)
if (rng->NameCRC == crc)
{
arc << rng->sfmt.u[i];
arc("index", rng->idx)
.Array("u", rng->sfmt.u, SFMT::N32);
break;
}
break;
}
}
if (rng == NULL)
{ // The RNG was removed. Skip it.
int idx;
DWORD sfmt;
arc << idx;
for (int i = 0; i < SFMT::N32; ++i)
{
arc << sfmt;
}
arc.EndObject();
}
}
png->File->ResetFilePtr();
arc.EndArray();
}
}

View file

@ -39,7 +39,7 @@
#include "basictypes.h"
#include "sfmt/SFMT.h"
struct PNGHandle;
class FSerializer;
class FRandom
{
@ -174,8 +174,8 @@ public:
// Static interface
static void StaticClearRandom ();
static DWORD StaticSumSeeds ();
static void StaticReadRNGState (PNGHandle *png);
static void StaticWriteRNGState (FILE *file);
static void StaticReadRNGState (FSerializer &arc);
static void StaticWriteRNGState (FSerializer &file);
static FRandom *StaticFindRNG(const char *name);
#ifndef NDEBUG

View file

@ -46,6 +46,8 @@
#include "doomstat.h"
#include "gi.h"
#include "d_gui.h"
#include "serializer.h"
#include "resourcefiles/resourcefile.h"
@ -86,6 +88,10 @@ protected:
int commentRight;
int commentBottom;
// this needs to be kept in memory so that the texture can access it when it needs to.
FileReader *currentSavePic;
TArray<char> SavePicData;
static int InsertSaveNode (FSaveGameNode *node);
static void ReadSaveStrings ();
@ -213,7 +219,7 @@ void DLoadSaveMenu::ReadSaveStrings ()
LastSaved = LastAccessed = -1;
quickSaveSlot = NULL;
filter = G_BuildSaveName ("*.zds", -1);
filter = G_BuildSaveName ("*." SAVEGAME_EXT, -1);
filefirst = I_FindFirst (filter.GetChars(), &c_file);
if (filefirst != ((void *)(-1)))
{
@ -221,103 +227,141 @@ void DLoadSaveMenu::ReadSaveStrings ()
{
// I_FindName only returns the file's name and not its full path
FString filepath = G_BuildSaveName (I_FindName(&c_file), -1);
FILE *file = fopen (filepath, "rb");
if (file != NULL)
FResourceFile *savegame = FResourceFile::OpenResourceFile(filepath, nullptr, true, true);
if (savegame != nullptr)
{
PNGHandle *png;
char sig[16];
char title[SAVESTRINGSIZE+1];
bool oldVer = true;
bool addIt = false;
bool oldVer = 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[SAVESTRINGSIZE] = 0;
if (NULL != (png = M_VerifyPNG (file)))
FResourceLump *info = savegame->FindLump("info.json");
if (info == nullptr)
{
char *ver = M_GetPNGText (png, "ZDoom Save Version");
char *engine = M_GetPNGText (png, "Engine");
if (ver != NULL)
{
if (!M_GetPNGText (png, "Title", title, SAVESTRINGSIZE))
{
strncpy (title, I_FindName(&c_file), SAVESTRINGSIZE);
}
if (strncmp (ver, SAVESIG, 9) == 0 &&
atoi (ver+9) >= MINSAVEVER &&
engine != NULL)
{
// Was saved with a compatible ZDoom version,
// so check if it's for the current game.
// If it is, add it. Otherwise, ignore it.
char *iwad = M_GetPNGText (png, "Game WAD");
if (iwad != NULL)
{
if (stricmp (iwad, Wads.GetWadName (FWadCollection::IWAD_FILENUM)) == 0)
{
addIt = true;
oldVer = false;
missing = !G_CheckSaveGameWads (png, false);
}
delete[] iwad;
}
}
else
{ // An old version
addIt = true;
}
delete[] ver;
}
if (engine != NULL)
{
delete[] engine;
}
delete png;
// savegame info not found. This is not a savegame so leave it alone.
delete savegame;
continue;
}
else
void *data = info->CacheLump();
FSerializer arc;
if (arc.OpenReader((const char *)data, info->LumpSize))
{
fseek (file, 0, SEEK_SET);
if (fread (sig, 1, 16, file) == 16)
int savever = 0;
FString engine;
FString iwad;
FString title;
arc("Save Version", savever);
arc("Engine", engine);
arc("Game WAD", iwad);
arc("Title", title);
if (engine.Compare(GAMESIG) != 0 || savever > SAVEVER)
{
if (strncmp (sig, "ZDOOMSAVE", 9) == 0)
{
if (fread (title, 1, SAVESTRINGSIZE, file) == SAVESTRINGSIZE)
{
addIt = true;
}
}
else
{
memcpy (title, sig, 16);
if (fread (title + 16, 1, SAVESTRINGSIZE-16, file) == SAVESTRINGSIZE-16 &&
fread (sig, 1, 16, file) == 16 &&
strncmp (sig, "ZDOOMSAVE", 9) == 0)
{
addIt = true;
}
}
// 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(FWadCollection::IWAD_FILENUM)) == 0)
{
missing = !G_CheckSaveGameWads(arc, false);
}
else
{
// different game. Skip this.
delete savegame;
continue;
}
}
if (addIt)
{
FSaveGameNode *node = new FSaveGameNode;
node->Filename = filepath;
node->bOldVersion = oldVer;
node->bMissingWads = missing;
memcpy (node->Title, title, SAVESTRINGSIZE);
InsertSaveNode (node);
strncpy(node->Title, title.GetChars(), SAVESTRINGSIZE);
InsertSaveNode(node);
delete savegame;
}
}
else // check for old formats.
{
FILE *file = fopen (filepath, "rb");
if (file != NULL)
{
PNGHandle *png;
char sig[16];
char title[SAVESTRINGSIZE+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[SAVESTRINGSIZE] = 0;
if (NULL != (png = M_VerifyPNG (file)))
{
char *ver = M_GetPNGText (png, "ZDoom Save Version");
if (ver != NULL)
{
// An old version
if (!M_GetPNGText(png, "Title", title, SAVESTRINGSIZE))
{
strncpy(title, I_FindName(&c_file), SAVESTRINGSIZE);
}
addIt = true;
delete[] ver;
}
delete png;
}
else
{
fseek (file, 0, SEEK_SET);
if (fread (sig, 1, 16, file) == 16)
{
if (strncmp (sig, "ZDOOMSAVE", 9) == 0)
{
if (fread (title, 1, SAVESTRINGSIZE, file) == SAVESTRINGSIZE)
{
addIt = true;
}
}
else
{
memcpy (title, sig, 16);
if (fread (title + 16, 1, SAVESTRINGSIZE-16, file) == SAVESTRINGSIZE-16 &&
fread (sig, 1, 16, file) == 16 &&
strncmp (sig, "ZDOOMSAVE", 9) == 0)
{
addIt = true;
}
}
}
}
if (addIt)
{
FSaveGameNode *node = new FSaveGameNode;
node->Filename = filepath;
node->bOldVersion = true;
node->bMissingWads = false;
memcpy (node->Title, title, SAVESTRINGSIZE);
InsertSaveNode (node);
}
fclose (file);
}
fclose (file);
}
} while (I_FindNext (filefirst, &c_file) == 0);
I_FindClose (filefirst);
@ -407,6 +451,7 @@ DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc)
listboxHeight = listboxRows * rowHeight + 1;
listboxRight = listboxLeft + listboxWidth;
listboxBottom = listboxTop + listboxHeight;
currentSavePic = nullptr;
commentLeft = savepicLeft;
commentTop = savepicTop + savepicHeight + 16;
@ -418,6 +463,8 @@ DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc)
void DLoadSaveMenu::Destroy()
{
if (currentSavePic != nullptr) delete currentSavePic;
currentSavePic = nullptr;
ClearSaveStuff ();
}
@ -429,17 +476,23 @@ void DLoadSaveMenu::Destroy()
void DLoadSaveMenu::UnloadSaveData ()
{
if (SavePic != NULL)
if (SavePic != nullptr)
{
delete SavePic;
}
if (SaveComment != NULL)
if (SaveComment != nullptr)
{
V_FreeBrokenLines (SaveComment);
}
if (currentSavePic != nullptr)
{
delete currentSavePic;
}
SavePic = NULL;
SaveComment = NULL;
SavePic = nullptr;
SaveComment = nullptr;
currentSavePic = nullptr;
SavePicData.Clear();
}
//=============================================================================
@ -465,8 +518,7 @@ void DLoadSaveMenu::ClearSaveStuff ()
void DLoadSaveMenu::ExtractSaveData (int index)
{
FILE *file;
PNGHandle *png;
FResourceFile *resf;
FSaveGameNode *node;
UnloadSaveData ();
@ -475,66 +527,61 @@ void DLoadSaveMenu::ExtractSaveData (int index)
(node = SaveGames[index]) &&
!node->Filename.IsEmpty() &&
!node->bOldVersion &&
(file = fopen (node->Filename.GetChars(), "rb")) != NULL)
(resf = FResourceFile::OpenResourceFile(node->Filename.GetChars(), nullptr, true)) != nullptr)
{
if (NULL != (png = M_VerifyPNG (file)))
FResourceLump *info = resf->FindLump("info.json");
if (info == nullptr)
{
char *time, *pcomment, *comment;
size_t commentlen, totallen, timelen;
// this should not happen because the file has already been verified.
return;
}
void *data = info->CacheLump();
FSerializer arc;
if (arc.OpenReader((const char *)data, info->LumpSize))
{
FString time, pcomment, comment;
// Extract comment
time = M_GetPNGText (png, "Creation Time");
pcomment = M_GetPNGText (png, "Comment");
if (pcomment != NULL)
{
commentlen = strlen (pcomment);
}
else
{
commentlen = 0;
}
if (time != NULL)
{
timelen = strlen (time);
totallen = timelen + commentlen + 3;
}
else
{
timelen = 0;
totallen = commentlen + 1;
}
if (totallen != 0)
{
comment = new char[totallen];
arc("Creation Time", time);
arc("Comment", pcomment);
if (timelen)
{
memcpy (comment, time, timelen);
comment[timelen] = '\n';
comment[timelen+1] = '\n';
timelen += 2;
}
if (commentlen)
{
memcpy (comment + timelen, pcomment, commentlen);
}
comment[timelen+commentlen] = 0;
SaveComment = V_BreakLines (SmallFont, 216*screen->GetWidth()/640/CleanXfac, comment);
delete[] comment;
delete[] time;
delete[] pcomment;
}
comment = time;
if (time.Len() > 0) comment += "\n\n";
comment += pcomment;
SaveComment = V_BreakLines (SmallFont, 216*screen->GetWidth()/640/CleanXfac, comment.GetChars());
// Extract pic
SavePic = PNGTexture_CreateFromFile(png, node->Filename);
delete png;
if (SavePic->GetWidth() == 1 && SavePic->GetHeight() == 1)
FResourceLump *pic = resf->FindLump("savepic.png");
if (pic != nullptr)
{
delete SavePic;
SavePic = NULL;
FileReader *reader = pic->NewReader();
if (reader != nullptr)
{
// copy to a memory buffer which gets accessed through a memory reader and PNGHandle.
// We cannot use the actual lump as backing for the texture because that requires keeping the
// savegame file open.
SavePicData.Resize(pic->LumpSize);
reader->Read(&SavePicData[0], pic->LumpSize);
reader = new MemoryReader(&SavePicData[0], SavePicData.Size());
PNGHandle *png = M_VerifyPNG(reader);
if (png != nullptr)
{
SavePic = PNGTexture_CreateFromFile(png, node->Filename);
currentSavePic = reader; // must be kept so that the texture can read from it.
delete png;
if (SavePic->GetWidth() == 1 && SavePic->GetHeight() == 1)
{
delete SavePic;
SavePic = nullptr;
delete currentSavePic;
currentSavePic = nullptr;
SavePicData.Clear();
}
}
}
}
}
fclose (file);
delete resf;
}
}

File diff suppressed because it is too large Load diff

View file

@ -44,6 +44,7 @@
class FFont;
class FileReader;
struct line_t;
enum
@ -94,8 +95,8 @@ public:
void PurgeStrings();
void Clear();
void Dump() const;
void ReadStrings(PNGHandle *png, DWORD id);
void WriteStrings(FILE *file, DWORD id) const;
void ReadStrings(FSerializer &file, const char *key);
void WriteStrings(FSerializer &file, const char *key) const;
private:
int FindString(const char *str, size_t len, unsigned int h, unsigned int bucketnum);
@ -120,10 +121,9 @@ private:
extern ACSStringPool GlobalACSStrings;
void P_CollectACSGlobalStrings();
void P_ReadACSVars(PNGHandle *);
void P_WriteACSVars(FILE*);
void P_ReadACSVars(FSerializer &);
void P_WriteACSVars(FSerializer &);
void P_ClearACSVars(bool);
void P_SerializeACSScriptNumber(FArchive &arc, int &scriptnum, bool was2byte);
struct ACSProfileInfo
{
@ -325,7 +325,7 @@ public:
static void StaticUnloadModules ();
static bool StaticCheckAllGood ();
static FBehavior *StaticGetModule (int lib);
static void StaticSerializeModuleStates (FArchive &arc);
static void StaticSerializeModuleStates (FSerializer &arc);
static void StaticMarkLevelVarStrings();
static void StaticLockLevelVarStrings();
static void StaticUnlockLevelVarStrings();
@ -369,8 +369,8 @@ private:
void UnescapeStringTable(BYTE *chunkstart, BYTE *datastart, bool haspadding);
int FindStringInChunk (DWORD *chunk, const char *varname) const;
void SerializeVars (FArchive &arc);
void SerializeVarSet (FArchive &arc, SDWORD *vars, int max);
void SerializeVars (FSerializer &arc);
void SerializeVarSet (FSerializer &arc, SDWORD *vars, int max);
void MarkMapVarStrings() const;
void LockMapVarStrings() const;
@ -860,7 +860,7 @@ public:
const int *args, int argcount, int flags);
~DLevelScript ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
int RunScript ();
inline void SetState (EScriptState newstate) { state = newstate; }
@ -870,22 +870,21 @@ public:
void MarkLocalVarStrings() const
{
GlobalACSStrings.MarkStringArray(localvars, numlocalvars);
GlobalACSStrings.MarkStringArray(&Localvars[0], Localvars.Size());
}
void LockLocalVarStrings() const
{
GlobalACSStrings.LockStringArray(localvars, numlocalvars);
GlobalACSStrings.LockStringArray(&Localvars[0], Localvars.Size());
}
void UnlockLocalVarStrings() const
{
GlobalACSStrings.UnlockStringArray(localvars, numlocalvars);
GlobalACSStrings.UnlockStringArray(&Localvars[0], Localvars.Size());
}
protected:
DLevelScript *next, *prev;
int script;
SDWORD *localvars;
int numlocalvars;
TArray<int32_t> Localvars;
int *pc;
EScriptState state;
int statedata;
@ -945,7 +944,7 @@ public:
DACSThinker ();
~DACSThinker ();
void Serialize (FArchive &arc);
void Serialize(FSerializer &arc);
void Tick ();
typedef TMap<int, DLevelScript *> ScriptMap;
@ -966,8 +965,6 @@ private:
// The structure used to control scripts between maps
struct acsdefered_t
{
struct acsdefered_t *next;
enum EType
{
defexecute,
@ -980,6 +977,6 @@ struct acsdefered_t
int playernum;
};
FArchive &operator<< (FArchive &arc, acsdefered_t *&defer);
FSerializer &Serialize(FSerializer &arc, const char *key, acsdefered_t &defer, acsdefered_t *def);
#endif //__P_ACS_H__

Some files were not shown because too many files have changed in this diff Show more