- save global savegame data to JSON as well.

This is incomplete and untested, just a safety commit before going on.
This commit is contained in:
Christoph Oelckers 2016-09-21 12:19:13 +02:00
parent dbea80e943
commit 810ef8f775
27 changed files with 346 additions and 461 deletions

View file

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

View file

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

View file

@ -117,91 +117,6 @@ void DThinker::SaveList(FSerializer &arc, DThinker *node)
} }
} }
void DThinker::SerializeAll(FArchive &arc, bool hubLoad)
{
#if 0
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())
{
for (statcount = i = 0; i <= MAX_STATNUM; i++)
{
statcount += (!Thinkers[i].IsEmpty() || !FreshThinkers[i].IsEmpty());
}
arc << statcount;
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
}
}
}
else
{
// Prevent the constructor from inserting thinkers into a list.
bSerialOverride = true;
try
{
arc << statcount;
while (statcount > 0)
{
arc << stat << thinker;
while (thinker != NULL)
{
// This may be a player stored in their ancillary list. Remove
// them first before inserting them into the new list.
if (thinker->NextThinker != NULL)
{
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 in to any list.
}
else if (thinker->ObjectFlags & OF_JustSpawned)
{
FreshThinkers[stat].AddTail(thinker);
}
else
{
Thinkers[stat].AddTail(thinker);
}
arc << thinker;
}
statcount--;
}
}
catch (class CDoomError &)
{
bSerialOverride = false;
DestroyAllThinkers();
throw;
}
bSerialOverride = false;
}
#endif
}
DThinker::DThinker (int statnum) throw() DThinker::DThinker (int statnum) throw()
{ {
NextThinker = NULL; NextThinker = NULL;

View file

@ -84,7 +84,6 @@ public:
DestroyThinkersInList(Thinkers[statnum]); DestroyThinkersInList(Thinkers[statnum]);
DestroyThinkersInList(FreshThinkers[statnum]); DestroyThinkersInList(FreshThinkers[statnum]);
} }
static void SerializeAll (FArchive &arc, bool keepPlayers);
static void SerializeThinkers(FSerializer &arc, bool keepPlayers); static void SerializeThinkers(FSerializer &arc, bool keepPlayers);
static void MarkRoots(); static void MarkRoots();

View file

@ -84,6 +84,7 @@
#include "a_morph.h" #include "a_morph.h"
#include "p_spec.h" #include "p_spec.h"
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "serializer.h"
#include <zlib.h> #include <zlib.h>
@ -110,8 +111,7 @@ void G_DoWorldDone (void);
void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description); void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description);
void G_DoAutoSave (); void G_DoAutoSave ();
void STAT_Write(FILE *file); void STAT_Serialize(FSerializer &file);
void STAT_Read(PNGHandle *png);
FIntCVar gameskill ("skill", 2, CVAR_SERVERINFO|CVAR_LATCH); FIntCVar gameskill ("skill", 2, CVAR_SERVERINFO|CVAR_LATCH);
CVAR (Int, deathmatch, 0, CVAR_SERVERINFO|CVAR_LATCH); CVAR (Int, deathmatch, 0, CVAR_SERVERINFO|CVAR_LATCH);
@ -2045,7 +2045,7 @@ FString G_BuildSaveName (const char *prefix, int slot)
name << prefix; name << prefix;
if (slot >= 0) if (slot >= 0)
{ {
name.AppendFormat("%d.zds", slot); name.AppendFormat("%d.zds" SAVEGAME_EXT, slot);
} }
return name; return name;
} }
@ -2102,27 +2102,24 @@ void G_DoAutoSave ()
} }
static void PutSaveWads (FILE *file) static void PutSaveWads (FSerializer &arc)
{ {
#if 0 // SAVEGAME
const char *name; const char *name;
// Name of IWAD // Name of IWAD
name = Wads.GetWadName (FWadCollection::IWAD_FILENUM); name = Wads.GetWadName (FWadCollection::IWAD_FILENUM);
M_AppendPNGText (file, "Game WAD", name); arc.AddString("Game WAD", name);
// Name of wad the map resides in // Name of wad the map resides in
if (Wads.GetLumpFile (level.lumpnum) > 1) if (Wads.GetLumpFile (level.lumpnum) > 1)
{ {
name = Wads.GetWadName (Wads.GetLumpFile (level.lumpnum)); name = Wads.GetWadName (Wads.GetLumpFile (level.lumpnum));
M_AppendPNGText (file, "Map WAD", name); arc.AddString("Map WAD", name);
} }
#endif
} }
static void PutSaveComment (FILE *file) static void PutSaveComment (FSerializer &arc)
{ {
#if 0 // SAVEGAME
char comment[256]; char comment[256];
const char *readableTime; const char *readableTime;
WORD len; WORD len;
@ -2136,7 +2133,7 @@ static void PutSaveComment (FILE *file)
strncpy (comment+15, readableTime+10, 9); strncpy (comment+15, readableTime+10, 9);
comment[24] = 0; comment[24] = 0;
M_AppendPNGText (file, "Creation Time", comment); arc.AddString("Creation Time", comment);
// Get level name // Get level name
//strcpy (comment, level.level_name); //strcpy (comment, level.level_name);
@ -2151,8 +2148,7 @@ static void PutSaveComment (FILE *file)
comment[len+16] = 0; comment[len+16] = 0;
// Write out the comment // Write out the comment
M_AppendPNGText (file, "Comment", comment); arc.AddString("Comment", comment);
#endif
} }
static void PutSavePic (FileWriter *file, int width, int height) static void PutSavePic (FileWriter *file, int width, int height)
@ -2169,6 +2165,8 @@ static void PutSavePic (FileWriter *file, int width, int height)
void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description) void G_DoSaveGame (bool okForQuicksave, FString filename, const char *description)
{ {
TArray<FCompressedBuffer> savegame_content;
char buf[100]; char buf[100];
// Do not even try, if we're not in a level. (Can happen after // Do not even try, if we're not in a level. (Can happen after
@ -2180,7 +2178,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
if (demoplayback) if (demoplayback)
{ {
filename = G_BuildSaveName ("demosave.zds", -1); filename = G_BuildSaveName ("demosave." SAVEGAME_EXT, -1);
} }
if (cl_waitforsave) if (cl_waitforsave)
@ -2189,74 +2187,63 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
insave = true; insave = true;
G_SnapshotLevel (); 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) savegameinfo.OpenWriter();
{ savegameglobals.OpenWriter();
Printf ("Could not create savegame '%s'\n", filename.GetChars());
insave = false;
I_FreezeTime(false);
return;
}
SaveVersion = SAVEVER; SaveVersion = SAVEVER;
#if 0 // SAVEGAME PutSavePic(&savepic, SAVEPICWIDTH, SAVEPICHEIGHT);
PutSavePic (stdfile, SAVEPICWIDTH, SAVEPICHEIGHT);
mysnprintf(buf, countof(buf), GAMENAME " %s", GetVersionString()); mysnprintf(buf, countof(buf), GAMENAME " %s", GetVersionString());
M_AppendPNGText (stdfile, "Software", buf); // put some basic info into the PNG so that this isn't lost when the image gets extracted.
M_AppendPNGText (stdfile, "Engine", GAMESIG); M_AppendPNGText(&savepic, "Software", buf);
M_AppendPNGText (stdfile, "ZDoom Save Version", SAVESIG); M_AppendPNGText(&savepic, "Title", description);
M_AppendPNGText (stdfile, "Title", description); M_AppendPNGText(&savepic, "Current Map", level.MapName);
M_AppendPNGText (stdfile, "Current Map", level.MapName); M_FinishPNG(&savepic);
PutSaveWads (stdfile);
PutSaveComment (stdfile); savegameinfo.AddString("Software", buf)
.AddString("Engine", GAMESIG)
.AddString("Save Version", SAVESIG)
.AddString("Title", description)
.AddString("Current Map", level.MapName);
PutSaveWads (savegameinfo);
PutSaveComment (savegameinfo);
// Intermission stats for hubs // Intermission stats for hubs
G_WriteHubInfo(stdfile); G_SerializeHub(savegameglobals);
{ {
FString vars = C_GetMassCVarString(CVAR_SERVERINFO); 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) if (level.time != 0 || level.maptime != 0)
{ {
DWORD time[2] = { DWORD(BigLong(TICRATE)), DWORD(BigLong(level.time)) }; int tic = TICRATE;
M_AppendPNGChunk (stdfile, MAKE_ID('p','t','I','c'), (BYTE *)&time, 8); savegameglobals("ticrate", tic);
savegameglobals("leveltime", level.time);
} }
G_WriteSnapshots (stdfile); STAT_Serialize(savegameglobals);
STAT_Write(stdfile); FRandom::StaticWriteRNGState(savegameglobals);
FRandom::StaticWriteRNGState (stdfile); P_WriteACSDefereds(savegameglobals);
P_WriteACSDefereds (stdfile); P_WriteACSVars(savegameglobals);
P_WriteACSVars(stdfile);
if (NextSkill != -1) if (NextSkill != -1)
{ {
BYTE next = NextSkill; savegameglobals("nextskill", NextSkill);
M_AppendPNGChunk (stdfile, MAKE_ID('s','n','X','t'), &next, 1);
} }
M_FinishPNG (stdfile); //G_WriteSnapshots (stdfile);
fclose (stdfile);
M_NotifyNewSave (filename.GetChars(), description, okForQuicksave); M_NotifyNewSave (filename.GetChars(), description, okForQuicksave);
// Check whether the file is ok. // Check whether the file is ok. (todo when new format is ready)
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);
}
#endif
bool success = true; bool success = true;
if (success) if (success)
{ {

View file

@ -43,7 +43,7 @@
#include "m_png.h" #include "m_png.h"
#include "gstrings.h" #include "gstrings.h"
#include "wi_stuff.h" #include "wi_stuff.h"
#include "farchive.h" #include "serializer.h"
//========================================================================== //==========================================================================
@ -54,7 +54,7 @@
struct FHubInfo struct FHubInfo
{ {
int finished_ep; int levelnum;
int maxkills; int maxkills;
int maxitems; int maxitems;
@ -65,7 +65,7 @@ struct FHubInfo
FHubInfo &operator=(const wbstartstruct_t &wbs) FHubInfo &operator=(const wbstartstruct_t &wbs)
{ {
finished_ep = wbs.finished_ep; levelnum = wbs.finished_ep;
maxkills = wbs.maxkills; maxkills = wbs.maxkills;
maxsecret= wbs.maxsecret; maxsecret= wbs.maxsecret;
maxitems = wbs.maxitems; maxitems = wbs.maxitems;
@ -80,54 +80,54 @@ static TArray<FHubInfo> hubdata;
void G_LeavingHub(int mode, cluster_info_t * cluster, wbstartstruct_t * wbs) 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) 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; break;
} }
} }
if (i==hubdata.Size()) if (i == hubdata.Size())
{ {
hubdata[hubdata.Reserve(1)] = *wbs; hubdata[hubdata.Reserve(1)] = *wbs;
} }
hubdata[i].finished_ep=level.levelnum; hubdata[i].levelnum = level.levelnum;
if (!multiplayer && !deathmatch) if (!multiplayer && !deathmatch)
{ {
// The player counters don't work in hubs // The player counters don't work in hubs
hubdata[i].plyr[0].skills=level.killed_monsters; hubdata[i].plyr[0].skills = level.killed_monsters;
hubdata[i].plyr[0].sitems=level.found_items; hubdata[i].plyr[0].sitems = level.found_items;
hubdata[i].plyr[0].ssecret=level.found_secrets; hubdata[i].plyr[0].ssecret = level.found_secrets;
} }
if (mode!=FINISH_SameHub) if (mode != FINISH_SameHub)
{ {
wbs->maxkills=wbs->maxitems=wbs->maxsecret=0; wbs->maxkills = wbs->maxitems = wbs->maxsecret = 0;
for(i=0;i<MAXPLAYERS;i++) 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->maxkills += hubdata[i].maxkills;
wbs->maxitems += hubdata[i].maxitems; wbs->maxitems += hubdata[i].maxitems;
wbs->maxsecret += hubdata[i].maxsecret; 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].sitems += hubdata[i].plyr[j].sitems;
wbs->plyr[j].skills += hubdata[i].plyr[j].skills; wbs->plyr[j].skills += hubdata[i].plyr[j].skills;
wbs->plyr[j].ssecret += hubdata[i].plyr[j].ssecret; wbs->plyr[j].ssecret += hubdata[i].plyr[j].ssecret;
} }
} }
if (cluster->ClusterName.IsNotEmpty()) if (cluster->ClusterName.IsNotEmpty())
{ {
if (cluster->flags & CLUSTER_LOOKUPNAME) 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 // 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(); if (arc.BeginObject(key))
arc << i;
if (i>0)
{ {
if (arc.IsStoring()) arc.Write(&hubdata[0], i * sizeof(FHubInfo)); arc("in", h.in)
else ("kills", h.skills)
{ ("items", h.sitems)
hubdata.Resize(i); ("secrets", h.ssecret)
arc.Read(&hubdata[0], i * sizeof(FHubInfo)); ("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); if (arc.BeginObject(key))
G_SerializeHub(arc); {
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; arc("hubinfo", hubdata);
if ((chunklen = M_FindPNGChunk (png, HUBS_ID)) != 0)
{
FPNGChunkArchive arc (png->File->GetFile(), HUBS_ID, chunklen);
G_SerializeHub(arc);
}
} }
void G_ClearHubInfo() void G_ClearHubInfo()

View file

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

View file

@ -1748,38 +1748,33 @@ CCMD(listsnapshots)
// //
//========================================================================== //==========================================================================
static void writeDefereds (FArchive &arc, level_info_t *i) void P_WriteACSDefereds (FSerializer &arc)
{ {
arc << i->MapName << i->defered; bool found = false;
}
//========================================================================== // only write this stuff if needed
// for (auto &wi : wadlevelinfos)
//
//==========================================================================
void P_WriteACSDefereds (FILE *file)
{
FPNGChunkArchive *arc = NULL;
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{ {
if (wadlevelinfos[i].defered) if (wi.deferred.Size() > 0)
{ {
if (arc == NULL) found = true;
{ break;
arc = new FPNGChunkArchive (file, ACSD_ID);
}
writeDefereds (*arc, (level_info_t *)&wadlevelinfos[i]);
} }
} }
if (found && arc.BeginObject("deferred"))
if (arc != NULL)
{ {
// Signal end of defereds for (auto &wi : wadlevelinfos)
FString empty = ""; {
(*arc) << empty; if (wi.deferred.Size() > 0)
delete arc; {
if (wi.deferred.Size() > 0 && arc.BeginObject(nullptr))
{
arc(wi.MapName, wi.deferred)
.EndObject();
}
}
}
arc.EndObject();
} }
} }
@ -1790,6 +1785,7 @@ void P_WriteACSDefereds (FILE *file)
void P_ReadACSDefereds (PNGHandle *png) void P_ReadACSDefereds (PNGHandle *png)
{ {
#if 0
FString MapName; FString MapName;
size_t chunklen; size_t chunklen;
@ -1806,10 +1802,11 @@ void P_ReadACSDefereds (PNGHandle *png)
{ {
I_Error("Unknown map '%s' in savegame", MapName.GetChars()); I_Error("Unknown map '%s' in savegame", MapName.GetChars());
} }
arc << i->defered; arc << i->deferred;
} }
} }
png->File->ResetFilePtr(); png->File->ResetFilePtr();
#endif
} }

View file

@ -38,6 +38,7 @@
#include "doomdef.h" #include "doomdef.h"
#include "sc_man.h" #include "sc_man.h"
#include "s_sound.h" #include "s_sound.h"
#include "p_acs.h"
#include "textures/textures.h" #include "textures/textures.h"
#include "resourcefiles/file_zip.h" #include "resourcefiles/file_zip.h"
@ -224,8 +225,6 @@ enum ELevelFlags : unsigned int
}; };
struct acsdefered_t;
struct FSpecialAction struct FSpecialAction
{ {
FName Type; // this is initialized before the actors... FName Type; // this is initialized before the actors...
@ -297,7 +296,7 @@ struct level_info_t
int musicorder; int musicorder;
FCompressedBuffer Snapshot; FCompressedBuffer Snapshot;
DWORD snapshotVer; DWORD snapshotVer;
struct acsdefered_t *defered; TArray<acsdefered_t> deferred;
float skyspeed1; float skyspeed1;
float skyspeed2; float skyspeed2;
DWORD fadeto; DWORD fadeto;
@ -352,7 +351,10 @@ struct level_info_t
void Reset(); void Reset();
bool isValid(); bool isValid();
FString LookupLevelName (); FString LookupLevelName ();
void ClearDefered(); void ClearDefered()
{
deferred.Clear();
}
level_info_t *CheckLevelRedirect (); level_info_t *CheckLevelRedirect ();
template<class T> template<class T>

View file

@ -250,7 +250,7 @@ void level_info_t::Reset()
musicorder = 0; musicorder = 0;
Snapshot = { 0,0,0,0,nullptr }; Snapshot = { 0,0,0,0,nullptr };
snapshotVer = 0; snapshotVer = 0;
defered = 0; deferred.Clear();
skyspeed1 = skyspeed2 = 0.f; skyspeed1 = skyspeed2 = 0.f;
fadeto = 0; fadeto = 0;
outsidefog = 0xff000000; outsidefog = 0xff000000;
@ -334,23 +334,6 @@ FString level_info_t::LookupLevelName()
} }
//==========================================================================
//
//
//==========================================================================
void level_info_t::ClearDefered()
{
acsdefered_t *def = defered;
while (def)
{
acsdefered_t *next = def->next;
delete def;
def = next;
}
defered = NULL;
}
//========================================================================== //==========================================================================
// //
// //

View file

@ -50,10 +50,8 @@ CCMD(writejson)
DWORD t = I_MSTime(); DWORD t = I_MSTime();
FSerializer arc; FSerializer arc;
arc.OpenWriter(); arc.OpenWriter();
arc.BeginObject(nullptr);
G_SerializeLevel(arc, false); G_SerializeLevel(arc, false);
arc.WriteObjects(); arc.WriteObjects();
arc.EndObject();
DWORD tt = I_MSTime(); DWORD tt = I_MSTime();
Printf("JSON generation took %d ms\n", tt - t); Printf("JSON generation took %d ms\n", tt - t);
FILE *f = fopen("out.json", "wb"); FILE *f = fopen("out.json", "wb");

View file

@ -449,7 +449,7 @@ struct pcx_t
}; };
inline void putc(char chr, FileWriter *file) inline void putc(unsigned char chr, FileWriter *file)
{ {
file->Write(&chr, 1); file->Write(&chr, 1);
} }

View file

@ -61,7 +61,7 @@
#include "doomstat.h" #include "doomstat.h"
#include "m_random.h" #include "m_random.h"
#include "farchive.h" #include "serializer.h"
#include "b_bot.h" #include "b_bot.h"
#include "m_png.h" #include "m_png.h"
#include "m_crc32.h" #include "m_crc32.h"
@ -291,24 +291,29 @@ DWORD FRandom::StaticSumSeeds ()
// //
//========================================================================== //==========================================================================
void FRandom::StaticWriteRNGState (FILE *file) void FRandom::StaticWriteRNGState (FSerializer &arc)
{ {
FRandom *rng; 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 for (rng = FRandom::RNGList; rng != NULL; rng = rng->Next)
if (rng->NameCRC != 0)
{ {
arc << rng->NameCRC << rng->idx; // Only write those RNGs that have names
for (int i = 0; i < SFMT::N32; ++i) 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();
} }
} }
@ -323,6 +328,7 @@ void FRandom::StaticWriteRNGState (FILE *file)
void FRandom::StaticReadRNGState (PNGHandle *png) void FRandom::StaticReadRNGState (PNGHandle *png)
{ {
#if 0
FRandom *rng; FRandom *rng;
size_t len = M_FindPNGChunk (png, RAND_ID); size_t len = M_FindPNGChunk (png, RAND_ID);
@ -367,6 +373,7 @@ void FRandom::StaticReadRNGState (PNGHandle *png)
} }
png->File->ResetFilePtr(); png->File->ResetFilePtr();
} }
#endif
} }
//========================================================================== //==========================================================================

View file

@ -40,6 +40,7 @@
#include "sfmt/SFMT.h" #include "sfmt/SFMT.h"
struct PNGHandle; struct PNGHandle;
class FSerializer;
class FRandom class FRandom
{ {
@ -175,7 +176,7 @@ public:
static void StaticClearRandom (); static void StaticClearRandom ();
static DWORD StaticSumSeeds (); static DWORD StaticSumSeeds ();
static void StaticReadRNGState (PNGHandle *png); static void StaticReadRNGState (PNGHandle *png);
static void StaticWriteRNGState (FILE *file); static void StaticWriteRNGState (FSerializer &file);
static FRandom *StaticFindRNG(const char *name); static FRandom *StaticFindRNG(const char *name);
#ifndef NDEBUG #ifndef NDEBUG

View file

@ -213,7 +213,7 @@ void DLoadSaveMenu::ReadSaveStrings ()
LastSaved = LastAccessed = -1; LastSaved = LastAccessed = -1;
quickSaveSlot = NULL; quickSaveSlot = NULL;
filter = G_BuildSaveName ("*.zds", -1); filter = G_BuildSaveName ("*." SAVEGAME_EXT, -1);
filefirst = I_FindFirst (filter.GetChars(), &c_file); filefirst = I_FindFirst (filter.GetChars(), &c_file);
if (filefirst != ((void *)(-1))) if (filefirst != ((void *)(-1)))
{ {

View file

@ -770,11 +770,11 @@ void ACSStringPool::ReadStrings(PNGHandle *png, DWORD id)
// //
// ACSStringPool :: WriteStrings // ACSStringPool :: WriteStrings
// //
// Writes strings to a PNG chunk. // Writes strings to a serializer
// //
//============================================================================ //============================================================================
void ACSStringPool::WriteStrings(FILE *file, DWORD id) const void ACSStringPool::WriteStrings(FSerializer &file, const char *key) const
{ {
int32_t i, poolsize = (int32_t)Pool.Size(); int32_t i, poolsize = (int32_t)Pool.Size();
@ -782,20 +782,29 @@ void ACSStringPool::WriteStrings(FILE *file, DWORD id) const
{ // No need to write if we don't have anything. { // No need to write if we don't have anything.
return; return;
} }
FPNGChunkArchive arc(file, id); if (file.BeginObject(key))
arc << poolsize;
for (i = 0; i < poolsize; ++i)
{ {
PoolEntry *entry = &Pool[i]; file("poolsize", poolsize);
if (entry->Next != FREE_ENTRY) if (file.BeginArray("pool"))
{ {
arc.WriteCount(i); for (i = 0; i < poolsize; ++i)
arc.WriteString(entry->Str); {
arc.WriteCount(entry->LockCount); PoolEntry *entry = &Pool[i];
if (entry->Next != FREE_ENTRY)
{
if (file.BeginObject(nullptr))
{
file("index", i)
("string", entry->Str)
("lockcount", entry->LockCount)
.EndObject();
}
}
}
file.EndArray();
} }
file.EndObject();
} }
arc.WriteCount(-1);
} }
//============================================================================ //============================================================================
@ -945,7 +954,7 @@ void P_ClearACSVars(bool alsoglobal)
// //
//============================================================================ //============================================================================
static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id) static void WriteVars (FSerializer &file, SDWORD *vars, size_t count, const char *key)
{ {
size_t i, j; size_t i, j;
@ -963,12 +972,7 @@ static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id)
if (vars[j] != 0) if (vars[j] != 0)
break; break;
} }
FPNGChunkArchive arc (file, id); file.Array(key, vars, int(j+1));
for (i = 0; i <= j; ++i)
{
DWORD var = vars[i];
arc << var;
}
} }
} }
@ -1009,9 +1013,9 @@ static void ReadVars (PNGHandle *png, SDWORD *vars, size_t count, DWORD id)
// //
//============================================================================ //============================================================================
static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int count, DWORD id) static void WriteArrayVars (FSerializer &file, FWorldGlobalArray *vars, unsigned int count, const char *key)
{ {
unsigned int i, j; unsigned int i;
// Find the first non-empty array. // Find the first non-empty array.
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
@ -1021,28 +1025,31 @@ static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int co
} }
if (i < count) if (i < count)
{ {
// Find last non-empty array. Anything beyond the last stored array if (file.BeginObject(key))
// will be emptied at load time.
for (j = count-1; j > i; --j)
{ {
if (vars[j].CountUsed() != 0) for(;i<count;i++)
break;
}
FPNGChunkArchive arc (file, id);
arc.WriteCount (i);
arc.WriteCount (j);
for (; i <= j; ++i)
{
arc.WriteCount (vars[i].CountUsed());
FWorldGlobalArray::ConstIterator it(vars[i]);
const FWorldGlobalArray::Pair *pair;
while (it.NextPair (pair))
{ {
arc.WriteCount (pair->Key); if (vars[i].CountUsed())
arc.WriteCount (pair->Value); {
FString arraykey;
arraykey.Format("%d", i);
if (file.BeginObject(arraykey))
{
FWorldGlobalArray::ConstIterator it(vars[i]);
const FWorldGlobalArray::Pair *pair;
while (it.NextPair(pair))
{
arraykey.Format("%d", pair->Key);
int v = pair->Value;
file(arraykey.GetChars(), v);
}
file.EndObject();
}
}
} }
file.EndObject();
} }
} }
} }
@ -1108,13 +1115,13 @@ void P_ReadACSVars(PNGHandle *png)
// //
//============================================================================ //============================================================================
void P_WriteACSVars(FILE *stdfile) void P_WriteACSVars(FSerializer &arc)
{ {
WriteVars (stdfile, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r')); WriteVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars");
WriteVars (stdfile, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r')); WriteVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars");
WriteArrayVars (stdfile, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r')); WriteArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays");
WriteArrayVars (stdfile, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r')); WriteArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays");
GlobalACSStrings.WriteStrings(stdfile, MAKE_ID('a','s','T','r')); GlobalACSStrings.WriteStrings(arc, "acsglobalstrings");
} }
//---- Inventory functions --------------------------------------// //---- Inventory functions --------------------------------------//
@ -9672,15 +9679,13 @@ static void SetScriptState (int script, DLevelScript::EScriptState state)
void P_DoDeferedScripts () void P_DoDeferedScripts ()
{ {
acsdefered_t *def;
const ScriptPtr *scriptdata; const ScriptPtr *scriptdata;
FBehavior *module; FBehavior *module;
// Handle defered scripts in this step, too // Handle defered scripts in this step, too
def = level.info->defered; for(int i = level.info->deferred.Size()-1; i>=0; i--)
while (def)
{ {
acsdefered_t *next = def->next; acsdefered_t *def = &level.info->deferred[i];
switch (def->type) switch (def->type)
{ {
case acsdefered_t::defexecute: case acsdefered_t::defexecute:
@ -9711,39 +9716,35 @@ void P_DoDeferedScripts ()
DPrintf (DMSG_SPAMMY, "Deferred terminate of %s\n", ScriptPresentation(def->script).GetChars()); DPrintf (DMSG_SPAMMY, "Deferred terminate of %s\n", ScriptPresentation(def->script).GetChars());
break; break;
} }
delete def;
def = next;
} }
level.info->defered = NULL; level.info->deferred.Clear();
} }
static void addDefered (level_info_t *i, acsdefered_t::EType type, int script, const int *args, int argcount, AActor *who) static void addDefered (level_info_t *i, acsdefered_t::EType type, int script, const int *args, int argcount, AActor *who)
{ {
if (i) if (i)
{ {
acsdefered_t *def = new acsdefered_t; acsdefered_t &def = i->deferred[i->deferred.Reserve(1)];
int j; int j;
def->next = i->defered; def.type = type;
def->type = type; def.script = script;
def->script = script; for (j = 0; (size_t)j < countof(def.args) && j < argcount; ++j)
for (j = 0; (size_t)j < countof(def->args) && j < argcount; ++j)
{ {
def->args[j] = args[j]; def.args[j] = args[j];
} }
while ((size_t)j < countof(def->args)) while ((size_t)j < countof(def.args))
{ {
def->args[j++] = 0; def.args[j++] = 0;
} }
if (who != NULL && who->player != NULL) if (who != NULL && who->player != NULL)
{ {
def->playernum = int(who->player - players); def.playernum = int(who->player - players);
} }
else else
{ {
def->playernum = -1; def.playernum = -1;
} }
i->defered = def;
DPrintf (DMSG_SPAMMY, "%s on map %s deferred\n", ScriptPresentation(script).GetChars(), i->MapName.GetChars()); DPrintf (DMSG_SPAMMY, "%s on map %s deferred\n", ScriptPresentation(script).GetChars(), i->MapName.GetChars());
} }
} }
@ -9821,43 +9822,15 @@ void P_TerminateScript (int script, const char *map)
SetScriptState (script, DLevelScript::SCRIPT_PleaseRemove); SetScriptState (script, DLevelScript::SCRIPT_PleaseRemove);
} }
FArchive &operator<< (FArchive &arc, acsdefered_t *&defertop) FSerializer &Serialize(FSerializer &arc, const char *key, acsdefered_t &defer, acsdefered_t *def)
{ {
BYTE more; if (arc.BeginObject(key))
if (arc.IsStoring ())
{ {
acsdefered_t *defer = defertop; arc.Enum("type", defer.type)
more = 1; .ScriptNum("script", defer.script)
while (defer) .Array("args", defer.args, 3)
{ ("player", defer.playernum)
BYTE type; .EndObject();
arc << more;
type = (BYTE)defer->type;
arc << type;
P_SerializeACSScriptNumber(arc, defer->script, false);
arc << defer->playernum << defer->args[0] << defer->args[1] << defer->args[2];
defer = defer->next;
}
more = 0;
arc << more;
}
else
{
acsdefered_t **defer = &defertop;
arc << more;
while (more)
{
*defer = new acsdefered_t;
arc << more;
(*defer)->type = (acsdefered_t::EType)more;
P_SerializeACSScriptNumber(arc, (*defer)->script, false);
arc << (*defer)->playernum << (*defer)->args[0] << (*defer)->args[1] << (*defer)->args[2];
defer = &((*defer)->next);
arc << more;
}
*defer = NULL;
} }
return arc; return arc;
} }

View file

@ -44,6 +44,8 @@
class FFont; class FFont;
class FileReader; class FileReader;
struct line_t;
struct PNGHandle;
enum enum
@ -95,7 +97,7 @@ public:
void Clear(); void Clear();
void Dump() const; void Dump() const;
void ReadStrings(PNGHandle *png, DWORD id); void ReadStrings(PNGHandle *png, DWORD id);
void WriteStrings(FILE *file, DWORD id) const; void WriteStrings(FSerializer &file, const char *key) const;
private: private:
int FindString(const char *str, size_t len, unsigned int h, unsigned int bucketnum); int FindString(const char *str, size_t len, unsigned int h, unsigned int bucketnum);
@ -121,9 +123,8 @@ extern ACSStringPool GlobalACSStrings;
void P_CollectACSGlobalStrings(); void P_CollectACSGlobalStrings();
void P_ReadACSVars(PNGHandle *); void P_ReadACSVars(PNGHandle *);
void P_WriteACSVars(FILE*); void P_WriteACSVars(FSerializer &);
void P_ClearACSVars(bool); void P_ClearACSVars(bool);
void P_SerializeACSScriptNumber(FArchive &arc, int &scriptnum, bool was2byte);
struct ACSProfileInfo struct ACSProfileInfo
{ {
@ -964,8 +965,6 @@ private:
// The structure used to control scripts between maps // The structure used to control scripts between maps
struct acsdefered_t struct acsdefered_t
{ {
struct acsdefered_t *next;
enum EType enum EType
{ {
defexecute, defexecute,
@ -978,6 +977,6 @@ struct acsdefered_t
int playernum; 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__ #endif //__P_ACS_H__

View file

@ -72,17 +72,6 @@
// Thinkers // Thinkers
// //
//
// P_ArchiveThinkers
//
void P_SerializeThinkers (FArchive &arc, bool hubLoad)
{
arc.EnableThinkers();
//DImpactDecal::Im ::SerializeTime (arc);
DThinker::SerializeAll (arc, hubLoad);
}
void P_DestroyThinkers(bool hubLoad) void P_DestroyThinkers(bool hubLoad)
{ {
if (hubLoad) if (hubLoad)

View file

@ -34,8 +34,8 @@
#ifndef __P_SAVEG_H__ #ifndef __P_SAVEG_H__
#define __P_SAVEG_H__ #define __P_SAVEG_H__
class FArchive;
struct PNGHandle; struct PNGHandle;
class FSerializer;
// Persistent storage/archiving. // Persistent storage/archiving.
// These are the load / save game routines. // These are the load / save game routines.
@ -43,7 +43,7 @@ struct PNGHandle;
void P_DestroyThinkers(bool hubLoad); void P_DestroyThinkers(bool hubLoad);
void P_ReadACSDefereds (PNGHandle *png); void P_ReadACSDefereds (PNGHandle *png);
void P_WriteACSDefereds (FILE *file); void P_WriteACSDefereds (FSerializer &);
void G_SerializeLevel(FSerializer &arc, bool hubLoad); void G_SerializeLevel(FSerializer &arc, bool hubLoad);

View file

@ -159,7 +159,6 @@ class FScanner;
class FBitmap; class FBitmap;
struct FCopyInfo; struct FCopyInfo;
class DInterpolation; class DInterpolation;
class FArchive;
enum enum
{ {

View file

@ -176,8 +176,6 @@ public:
} }
}; };
FArchive &operator<<(FArchive &arc, FSoundID &sid);
extern FRolloffInfo S_Rolloff; extern FRolloffInfo S_Rolloff;
extern BYTE *S_SoundCurve; extern BYTE *S_SoundCurve;
extern int S_SoundCurveSize; extern int S_SoundCurveSize;

View file

@ -149,11 +149,12 @@ struct FReader
// //
//========================================================================== //==========================================================================
bool FSerializer::OpenWriter() bool FSerializer::OpenWriter(bool randomaccess)
{ {
if (w != nullptr || r != nullptr) return false; if (w != nullptr || r != nullptr) return false;
w = new FWriter; w = new FWriter;
BeginObject(nullptr, randomaccess);
return true; return true;
} }
@ -587,6 +588,22 @@ FSerializer &FSerializer::StringPtr(const char *key, const char *&charptr)
// //
//========================================================================== //==========================================================================
FSerializer &FSerializer::AddString(const char *key, const char *charptr)
{
if (isWriting())
{
WriteKey(key);
w->mWriter.String(charptr);
}
return *this;
}
//==========================================================================
//
//
//
//==========================================================================
unsigned FSerializer::GetSize(const char *group) unsigned FSerializer::GetSize(const char *group)
{ {
if (isWriting()) return -1; // we do not know this when writing. if (isWriting()) return -1; // we do not know this when writing.
@ -657,6 +674,7 @@ void FSerializer::WriteObjects()
const char *FSerializer::GetOutput(unsigned *len) const char *FSerializer::GetOutput(unsigned *len)
{ {
if (isReading()) return nullptr; if (isReading()) return nullptr;
EndObject();
if (len != nullptr) if (len != nullptr)
{ {
*len = (unsigned)w->mOutString.GetSize(); *len = (unsigned)w->mOutString.GetSize();
@ -674,6 +692,7 @@ FCompressedBuffer FSerializer::GetCompressedOutput()
{ {
if (isReading()) return{ 0,0,0,0,nullptr }; if (isReading()) return{ 0,0,0,0,nullptr };
FCompressedBuffer buff; FCompressedBuffer buff;
EndObject();
buff.mSize = (unsigned)w->mOutString.GetSize(); buff.mSize = (unsigned)w->mOutString.GetSize();
buff.mZipFlags = 0; buff.mZipFlags = 0;

View file

@ -75,6 +75,7 @@ public:
FSerializer &Terrain(const char *key, int &terrain, int *def = nullptr); FSerializer &Terrain(const char *key, int &terrain, int *def = nullptr);
FSerializer &Sprite(const char *key, int32_t &spritenum, int32_t *def); FSerializer &Sprite(const char *key, int32_t &spritenum, int32_t *def);
FSerializer &StringPtr(const char *key, const char *&charptr); // This only retrieves the address but creates no permanent copy of the string unlike the regular char* serializer. FSerializer &StringPtr(const char *key, const char *&charptr); // This only retrieves the address but creates no permanent copy of the string unlike the regular char* serializer.
FSerializer &AddString(const char *key, const char *charptr);
FSerializer &ScriptNum(const char *key, int &num); FSerializer &ScriptNum(const char *key, int &num);
bool isReading() const bool isReading() const
{ {

View file

@ -70,7 +70,7 @@
#include "r_sky.h" #include "r_sky.h"
#include "p_lnspec.h" #include "p_lnspec.h"
#include "m_crc32.h" #include "m_crc32.h"
#include "farchive.h" #include "serializer.h"
CVAR(Int, savestatistics, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, savestatistics, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(String, statfile, "zdoomstat.txt", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(String, statfile, "zdoomstat.txt", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -87,7 +87,7 @@ struct OneLevel
int totalkills, killcount; int totalkills, killcount;
int totalsecrets, secretcount; int totalsecrets, secretcount;
int leveltime; int leveltime;
char levelname[9]; FString Levelname;
}; };
// Current game's statistics // Current game's statistics
@ -408,13 +408,12 @@ static void StoreLevelStats()
{ {
for(i=0;i<LevelData.Size();i++) for(i=0;i<LevelData.Size();i++)
{ {
if (!stricmp(LevelData[i].levelname, level.MapName)) break; if (!LevelData[i].Levelname.CompareNoCase(level.MapName)) break;
} }
if (i==LevelData.Size()) if (i==LevelData.Size())
{ {
LevelData.Reserve(1); LevelData.Reserve(1);
strncpy(LevelData[i].levelname, level.MapName, 8); LevelData[i].Levelname = level.MapName;
LevelData[i].levelname[8] = 0;
} }
LevelData[i].totalkills = level.total_monsters; LevelData[i].totalkills = level.total_monsters;
LevelData[i].killcount = level.killed_monsters; LevelData[i].killcount = level.killed_monsters;
@ -494,7 +493,7 @@ void STAT_ChangeLevel(const char *newl)
for(unsigned i = 0; i < LevelData.Size(); i++) for(unsigned i = 0; i < LevelData.Size(); i++)
{ {
FString lsection = LevelData[i].levelname; FString lsection = LevelData[i].Levelname;
lsection.ToUpper(); lsection.ToUpper();
infostring.Format("%4d/%4d, %3d/%3d", infostring.Format("%4d/%4d, %3d/%3d",
LevelData[i].killcount, LevelData[i].totalkills, LevelData[i].secretcount, LevelData[i].totalsecrets); LevelData[i].killcount, LevelData[i].totalkills, LevelData[i].secretcount, LevelData[i].totalsecrets);
@ -516,64 +515,51 @@ void STAT_ChangeLevel(const char *newl)
// //
//========================================================================== //==========================================================================
static void SerializeStatistics(FArchive &arc) FSerializer &Serialize(FSerializer &arc, const char *key, OneLevel &l, OneLevel *def)
{
if (arc.BeginObject(key))
{
arc("totalkills", l.totalkills)
("killcount", l.killcount)
("totalsecrets", l.totalsecrets)
("secretcount", l.secretcount)
("leveltime", l.leveltime)
("levelname", l.Levelname)
.EndObject();
}
}
void STAT_Serialize(FSerializer &arc)
{ {
FString startlevel; FString startlevel;
int i = LevelData.Size(); int i = LevelData.Size();
arc << i; if (arc.BeginObject("statistics"))
if (arc.IsLoading())
{ {
arc << startlevel; if (arc.isReading())
StartEpisode = NULL;
for(unsigned int j=0;j<AllEpisodes.Size();j++)
{ {
if (!AllEpisodes[j].mEpisodeMap.CompareNoCase(startlevel)) arc("startlevel", startlevel);
StartEpisode = NULL;
for (unsigned int j = 0; j < AllEpisodes.Size(); j++)
{ {
StartEpisode = &AllEpisodes[j]; if (!AllEpisodes[j].mEpisodeMap.CompareNoCase(startlevel))
break; {
StartEpisode = &AllEpisodes[j];
break;
}
} }
LevelData.Resize(i);
} }
LevelData.Resize(i); else
} {
else if (StartEpisode != NULL) startlevel = StartEpisode->mEpisodeMap;
{ arc("startlevel", startlevel);
if (StartEpisode != NULL) startlevel = StartEpisode->mEpisodeMap; }
arc << startlevel; arc("levels", LevelData);
} arc.EndObject();
for(int j = 0; j < i; j++)
{
OneLevel &l = LevelData[j];
arc << l.totalkills
<< l.killcount
<< l.totalsecrets
<< l.secretcount
<< l.leveltime;
if (arc.IsStoring()) arc.WriteName(l.levelname);
else strcpy(l.levelname, arc.ReadName());
} }
} }
#define STAT_ID MAKE_ID('s','T','a','t')
void STAT_Write(FILE *file)
{
FPNGChunkArchive arc (file, STAT_ID);
SerializeStatistics(arc);
}
void STAT_Read(PNGHandle *png)
{
DWORD chunkLen = (DWORD)M_FindPNGChunk (png, STAT_ID);
if (chunkLen != 0)
{
FPNGChunkArchive arc (png->File->GetFile(), STAT_ID, chunkLen);
SerializeStatistics(arc);
}
}
//========================================================================== //==========================================================================
// //
@ -588,7 +574,7 @@ FString GetStatString()
{ {
OneLevel *l = &LevelData[i]; OneLevel *l = &LevelData[i];
compose.AppendFormat("Level %s - Kills: %d/%d - Secrets: %d/%d - Time: %d:%02d\n", compose.AppendFormat("Level %s - Kills: %d/%d - Secrets: %d/%d - Time: %d:%02d\n",
l->levelname, l->killcount, l->totalkills, l->secretcount, l->totalsecrets, l->Levelname.GetChars(), l->killcount, l->totalkills, l->secretcount, l->totalsecrets,
l->leveltime/(60*TICRATE), (l->leveltime/TICRATE)%60); l->leveltime/(60*TICRATE), (l->leveltime/TICRATE)%60);
} }
return compose; return compose;

View file

@ -49,9 +49,6 @@
#include "m_alloc.h" #include "m_alloc.h"
class FArchive;
template<typename T> class TIterator template<typename T> class TIterator
{ {
public: public:
@ -83,8 +80,6 @@ struct FArray
template <class T, class TT=T> template <class T, class TT=T>
class TArray class TArray
{ {
template<class U, class UU> friend FArchive &operator<< (FArchive &arc, TArray<U,UU> &self);
public: public:
typedef TIterator<T> iterator; typedef TIterator<T> iterator;

View file

@ -9,7 +9,6 @@ struct FRemapTable;
struct FCopyInfo; struct FCopyInfo;
class FScanner; class FScanner;
class PClassInventory; class PClassInventory;
class FArchive;
// Texture IDs // Texture IDs
class FTextureManager; class FTextureManager;
@ -21,8 +20,6 @@ public:
FNullTextureID() : FTextureID(0) {} FNullTextureID() : FTextureID(0) {}
}; };
FArchive &operator<< (FArchive &arc, FTextureID &tex);
// //
// Animating textures and planes // Animating textures and planes
// //

View file

@ -37,26 +37,6 @@
void P_SerializeACSScriptNumber(FArchive &arc, int &scriptnum, bool was2byte)
{
arc << scriptnum;
// If the script number is negative, then it's really a name.
// So read/store the name after it.
if (scriptnum < 0)
{
if (arc.IsStoring())
{
arc.WriteName(FName(ENamedName(-scriptnum)).GetChars());
}
else
{
const char *nam = arc.ReadName();
scriptnum = -FName(nam);
}
}
}
#if 0 #if 0
// still needed as reference. // still needed as reference.
FCrap &FCrap::ReadObject(DObject* &obj, PClass *wanttype) FCrap &FCrap::ReadObject(DObject* &obj, PClass *wanttype)
@ -181,3 +161,63 @@ FCrap &FCrap::ReadObject(DObject* &obj, PClass *wanttype)
} }
#endif #endif
#if 0
void DThinker::SerializeAll(FArchive &arc, bool hubLoad)
{
DThinker *thinker;
BYTE stat;
int statcount;
int i;
if (arc.IsStoring())
{
}
else
{
// Prevent the constructor from inserting thinkers into a list.
bSerialOverride = true;
try
{
arc << statcount;
while (statcount > 0)
{
arc << stat << thinker;
while (thinker != NULL)
{
// This may be a player stored in their ancillary list. Remove
// them first before inserting them into the new list.
if (thinker->NextThinker != NULL)
{
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 in to any list.
}
else if (thinker->ObjectFlags & OF_JustSpawned)
{
FreshThinkers[stat].AddTail(thinker);
}
else
{
Thinkers[stat].AddTail(thinker);
}
arc << thinker;
}
statcount--;
}
}
catch (class CDoomError &)
{
bSerialOverride = false;
DestroyAllThinkers();
throw;
}
bSerialOverride = false;
}
}
#endif