mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- 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:
parent
dbea80e943
commit
810ef8f775
27 changed files with 346 additions and 461 deletions
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
@ -2580,7 +2580,7 @@ void D_DoomMain (void)
|
|||
{
|
||||
FString file(v);
|
||||
FixPathSeperator (file);
|
||||
DefaultExtension (file, ".zds");
|
||||
DefaultExtension (file, ".zds" SAVEGAME_EXT);
|
||||
G_LoadGame (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()
|
||||
{
|
||||
NextThinker = NULL;
|
||||
|
|
|
@ -84,7 +84,6 @@ public:
|
|||
DestroyThinkersInList(Thinkers[statnum]);
|
||||
DestroyThinkersInList(FreshThinkers[statnum]);
|
||||
}
|
||||
static void SerializeAll (FArchive &arc, bool keepPlayers);
|
||||
static void SerializeThinkers(FSerializer &arc, bool keepPlayers);
|
||||
static void MarkRoots();
|
||||
|
||||
|
|
105
src/g_game.cpp
105
src/g_game.cpp
|
@ -84,6 +84,7 @@
|
|||
#include "a_morph.h"
|
||||
#include "p_spec.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "serializer.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
|
@ -110,8 +111,7 @@ 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);
|
||||
|
||||
FIntCVar gameskill ("skill", 2, 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;
|
||||
if (slot >= 0)
|
||||
{
|
||||
name.AppendFormat("%d.zds", slot);
|
||||
name.AppendFormat("%d.zds" SAVEGAME_EXT, slot);
|
||||
}
|
||||
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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void PutSaveComment (FILE *file)
|
||||
static void PutSaveComment (FSerializer &arc)
|
||||
{
|
||||
#if 0 // SAVEGAME
|
||||
char comment[256];
|
||||
const char *readableTime;
|
||||
WORD len;
|
||||
|
@ -2136,7 +2133,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);
|
||||
|
@ -2151,8 +2148,7 @@ static void PutSaveComment (FILE *file)
|
|||
comment[len+16] = 0;
|
||||
|
||||
// Write out the comment
|
||||
M_AppendPNGText (file, "Comment", comment);
|
||||
#endif
|
||||
arc.AddString("Comment", comment);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
TArray<FCompressedBuffer> savegame_content;
|
||||
|
||||
char buf[100];
|
||||
|
||||
// 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)
|
||||
{
|
||||
filename = G_BuildSaveName ("demosave.zds", -1);
|
||||
filename = G_BuildSaveName ("demosave." SAVEGAME_EXT, -1);
|
||||
}
|
||||
|
||||
if (cl_waitforsave)
|
||||
|
@ -2189,74 +2187,63 @@ 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();
|
||||
savegameglobals.OpenWriter();
|
||||
|
||||
SaveVersion = SAVEVER;
|
||||
#if 0 // SAVEGAME
|
||||
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);
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
P_WriteACSVars(stdfile);
|
||||
STAT_Serialize(savegameglobals);
|
||||
FRandom::StaticWriteRNGState(savegameglobals);
|
||||
P_WriteACSDefereds(savegameglobals);
|
||||
P_WriteACSVars(savegameglobals);
|
||||
|
||||
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);
|
||||
//G_WriteSnapshots (stdfile);
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
// Check whether the file is ok. (todo when new format is ready)
|
||||
bool success = true;
|
||||
if (success)
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
#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
|
||||
|
|
|
@ -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;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
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)
|
||||
{
|
||||
arc = new FPNGChunkArchive (file, ACSD_ID);
|
||||
}
|
||||
writeDefereds (*arc, (level_info_t *)&wadlevelinfos[i]);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (arc != NULL)
|
||||
if (found && arc.BeginObject("deferred"))
|
||||
{
|
||||
// Signal end of defereds
|
||||
FString empty = "";
|
||||
(*arc) << empty;
|
||||
delete arc;
|
||||
for (auto &wi : wadlevelinfos)
|
||||
{
|
||||
if (wi.deferred.Size() > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
#if 0
|
||||
FString MapName;
|
||||
size_t chunklen;
|
||||
|
||||
|
@ -1806,10 +1802,11 @@ void P_ReadACSDefereds (PNGHandle *png)
|
|||
{
|
||||
I_Error("Unknown map '%s' in savegame", MapName.GetChars());
|
||||
}
|
||||
arc << i->defered;
|
||||
arc << i->deferred;
|
||||
}
|
||||
}
|
||||
png->File->ResetFilePtr();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "sc_man.h"
|
||||
#include "s_sound.h"
|
||||
#include "p_acs.h"
|
||||
#include "textures/textures.h"
|
||||
#include "resourcefiles/file_zip.h"
|
||||
|
||||
|
@ -224,8 +225,6 @@ enum ELevelFlags : unsigned int
|
|||
};
|
||||
|
||||
|
||||
struct acsdefered_t;
|
||||
|
||||
struct FSpecialAction
|
||||
{
|
||||
FName Type; // this is initialized before the actors...
|
||||
|
@ -297,7 +296,7 @@ struct level_info_t
|
|||
int musicorder;
|
||||
FCompressedBuffer Snapshot;
|
||||
DWORD snapshotVer;
|
||||
struct acsdefered_t *defered;
|
||||
TArray<acsdefered_t> deferred;
|
||||
float skyspeed1;
|
||||
float skyspeed2;
|
||||
DWORD fadeto;
|
||||
|
@ -352,7 +351,10 @@ struct level_info_t
|
|||
void Reset();
|
||||
bool isValid();
|
||||
FString LookupLevelName ();
|
||||
void ClearDefered();
|
||||
void ClearDefered()
|
||||
{
|
||||
deferred.Clear();
|
||||
}
|
||||
level_info_t *CheckLevelRedirect ();
|
||||
|
||||
template<class T>
|
||||
|
|
|
@ -250,7 +250,7 @@ void level_info_t::Reset()
|
|||
musicorder = 0;
|
||||
Snapshot = { 0,0,0,0,nullptr };
|
||||
snapshotVer = 0;
|
||||
defered = 0;
|
||||
deferred.Clear();
|
||||
skyspeed1 = skyspeed2 = 0.f;
|
||||
fadeto = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -50,10 +50,8 @@ CCMD(writejson)
|
|||
DWORD t = I_MSTime();
|
||||
FSerializer arc;
|
||||
arc.OpenWriter();
|
||||
arc.BeginObject(nullptr);
|
||||
G_SerializeLevel(arc, false);
|
||||
arc.WriteObjects();
|
||||
arc.EndObject();
|
||||
DWORD tt = I_MSTime();
|
||||
Printf("JSON generation took %d ms\n", tt - t);
|
||||
FILE *f = fopen("out.json", "wb");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,6 +328,7 @@ void FRandom::StaticWriteRNGState (FILE *file)
|
|||
|
||||
void FRandom::StaticReadRNGState (PNGHandle *png)
|
||||
{
|
||||
#if 0
|
||||
FRandom *rng;
|
||||
|
||||
size_t len = M_FindPNGChunk (png, RAND_ID);
|
||||
|
@ -367,6 +373,7 @@ void FRandom::StaticReadRNGState (PNGHandle *png)
|
|||
}
|
||||
png->File->ResetFilePtr();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "sfmt/SFMT.h"
|
||||
|
||||
struct PNGHandle;
|
||||
class FSerializer;
|
||||
|
||||
class FRandom
|
||||
{
|
||||
|
@ -175,7 +176,7 @@ public:
|
|||
static void StaticClearRandom ();
|
||||
static DWORD StaticSumSeeds ();
|
||||
static void StaticReadRNGState (PNGHandle *png);
|
||||
static void StaticWriteRNGState (FILE *file);
|
||||
static void StaticWriteRNGState (FSerializer &file);
|
||||
static FRandom *StaticFindRNG(const char *name);
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -213,7 +213,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)))
|
||||
{
|
||||
|
|
171
src/p_acs.cpp
171
src/p_acs.cpp
|
@ -770,11 +770,11 @@ void ACSStringPool::ReadStrings(PNGHandle *png, DWORD id)
|
|||
//
|
||||
// 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();
|
||||
|
||||
|
@ -782,20 +782,29 @@ void ACSStringPool::WriteStrings(FILE *file, DWORD id) const
|
|||
{ // No need to write if we don't have anything.
|
||||
return;
|
||||
}
|
||||
FPNGChunkArchive arc(file, id);
|
||||
|
||||
arc << poolsize;
|
||||
for (i = 0; i < poolsize; ++i)
|
||||
if (file.BeginObject(key))
|
||||
{
|
||||
PoolEntry *entry = &Pool[i];
|
||||
if (entry->Next != FREE_ENTRY)
|
||||
file("poolsize", poolsize);
|
||||
if (file.BeginArray("pool"))
|
||||
{
|
||||
arc.WriteCount(i);
|
||||
arc.WriteString(entry->Str);
|
||||
arc.WriteCount(entry->LockCount);
|
||||
for (i = 0; i < poolsize; ++i)
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -963,12 +972,7 @@ static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id)
|
|||
if (vars[j] != 0)
|
||||
break;
|
||||
}
|
||||
FPNGChunkArchive arc (file, id);
|
||||
for (i = 0; i <= j; ++i)
|
||||
{
|
||||
DWORD var = vars[i];
|
||||
arc << var;
|
||||
}
|
||||
file.Array(key, vars, int(j+1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
for (i = 0; i < count; ++i)
|
||||
|
@ -1021,28 +1025,31 @@ static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int co
|
|||
}
|
||||
if (i < count)
|
||||
{
|
||||
// Find last non-empty array. Anything beyond the last stored array
|
||||
// will be emptied at load time.
|
||||
for (j = count-1; j > i; --j)
|
||||
if (file.BeginObject(key))
|
||||
{
|
||||
if (vars[j].CountUsed() != 0)
|
||||
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))
|
||||
for(;i<count;i++)
|
||||
{
|
||||
arc.WriteCount (pair->Key);
|
||||
arc.WriteCount (pair->Value);
|
||||
if (vars[i].CountUsed())
|
||||
{
|
||||
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 (stdfile, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
|
||||
WriteArrayVars (stdfile, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
|
||||
WriteArrayVars (stdfile, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
|
||||
GlobalACSStrings.WriteStrings(stdfile, MAKE_ID('a','s','T','r'));
|
||||
WriteVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars");
|
||||
WriteVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars");
|
||||
WriteArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays");
|
||||
WriteArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays");
|
||||
GlobalACSStrings.WriteStrings(arc, "acsglobalstrings");
|
||||
}
|
||||
|
||||
//---- Inventory functions --------------------------------------//
|
||||
|
@ -9672,15 +9679,13 @@ static void SetScriptState (int script, DLevelScript::EScriptState state)
|
|||
|
||||
void P_DoDeferedScripts ()
|
||||
{
|
||||
acsdefered_t *def;
|
||||
const ScriptPtr *scriptdata;
|
||||
FBehavior *module;
|
||||
|
||||
// Handle defered scripts in this step, too
|
||||
def = level.info->defered;
|
||||
while (def)
|
||||
for(int i = level.info->deferred.Size()-1; i>=0; i--)
|
||||
{
|
||||
acsdefered_t *next = def->next;
|
||||
acsdefered_t *def = &level.info->deferred[i];
|
||||
switch (def->type)
|
||||
{
|
||||
case acsdefered_t::defexecute:
|
||||
|
@ -9711,39 +9716,35 @@ void P_DoDeferedScripts ()
|
|||
DPrintf (DMSG_SPAMMY, "Deferred terminate of %s\n", ScriptPresentation(def->script).GetChars());
|
||||
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)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
acsdefered_t *def = new acsdefered_t;
|
||||
acsdefered_t &def = i->deferred[i->deferred.Reserve(1)];
|
||||
int j;
|
||||
|
||||
def->next = i->defered;
|
||||
def->type = type;
|
||||
def->script = script;
|
||||
for (j = 0; (size_t)j < countof(def->args) && j < argcount; ++j)
|
||||
def.type = type;
|
||||
def.script = script;
|
||||
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)
|
||||
{
|
||||
def->playernum = int(who->player - players);
|
||||
def.playernum = int(who->player - players);
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -9821,43 +9822,15 @@ void P_TerminateScript (int script, const char *map)
|
|||
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.IsStoring ())
|
||||
if (arc.BeginObject(key))
|
||||
{
|
||||
acsdefered_t *defer = defertop;
|
||||
more = 1;
|
||||
while (defer)
|
||||
{
|
||||
BYTE type;
|
||||
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;
|
||||
arc.Enum("type", defer.type)
|
||||
.ScriptNum("script", defer.script)
|
||||
.Array("args", defer.args, 3)
|
||||
("player", defer.playernum)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
|
11
src/p_acs.h
11
src/p_acs.h
|
@ -44,6 +44,8 @@
|
|||
|
||||
class FFont;
|
||||
class FileReader;
|
||||
struct line_t;
|
||||
struct PNGHandle;
|
||||
|
||||
|
||||
enum
|
||||
|
@ -95,7 +97,7 @@ public:
|
|||
void Clear();
|
||||
void Dump() const;
|
||||
void ReadStrings(PNGHandle *png, DWORD id);
|
||||
void WriteStrings(FILE *file, DWORD id) const;
|
||||
void WriteStrings(FSerializer &file, const char *key) const;
|
||||
|
||||
private:
|
||||
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_ReadACSVars(PNGHandle *);
|
||||
void P_WriteACSVars(FILE*);
|
||||
void P_WriteACSVars(FSerializer &);
|
||||
void P_ClearACSVars(bool);
|
||||
void P_SerializeACSScriptNumber(FArchive &arc, int &scriptnum, bool was2byte);
|
||||
|
||||
struct ACSProfileInfo
|
||||
{
|
||||
|
@ -964,8 +965,6 @@ private:
|
|||
// The structure used to control scripts between maps
|
||||
struct acsdefered_t
|
||||
{
|
||||
struct acsdefered_t *next;
|
||||
|
||||
enum EType
|
||||
{
|
||||
defexecute,
|
||||
|
@ -978,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__
|
||||
|
|
|
@ -72,17 +72,6 @@
|
|||
// 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)
|
||||
{
|
||||
if (hubLoad)
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
#ifndef __P_SAVEG_H__
|
||||
#define __P_SAVEG_H__
|
||||
|
||||
class FArchive;
|
||||
struct PNGHandle;
|
||||
class FSerializer;
|
||||
|
||||
// Persistent storage/archiving.
|
||||
// These are the load / save game routines.
|
||||
|
@ -43,7 +43,7 @@ struct PNGHandle;
|
|||
void P_DestroyThinkers(bool hubLoad);
|
||||
|
||||
void P_ReadACSDefereds (PNGHandle *png);
|
||||
void P_WriteACSDefereds (FILE *file);
|
||||
void P_WriteACSDefereds (FSerializer &);
|
||||
|
||||
void G_SerializeLevel(FSerializer &arc, bool hubLoad);
|
||||
|
||||
|
|
|
@ -159,7 +159,6 @@ class FScanner;
|
|||
class FBitmap;
|
||||
struct FCopyInfo;
|
||||
class DInterpolation;
|
||||
class FArchive;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -176,8 +176,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
FArchive &operator<<(FArchive &arc, FSoundID &sid);
|
||||
|
||||
extern FRolloffInfo S_Rolloff;
|
||||
extern BYTE *S_SoundCurve;
|
||||
extern int S_SoundCurveSize;
|
||||
|
|
|
@ -149,11 +149,12 @@ struct FReader
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FSerializer::OpenWriter()
|
||||
bool FSerializer::OpenWriter(bool randomaccess)
|
||||
{
|
||||
if (w != nullptr || r != nullptr) return false;
|
||||
w = new FWriter;
|
||||
|
||||
BeginObject(nullptr, randomaccess);
|
||||
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)
|
||||
{
|
||||
if (isWriting()) return -1; // we do not know this when writing.
|
||||
|
@ -657,6 +674,7 @@ void FSerializer::WriteObjects()
|
|||
const char *FSerializer::GetOutput(unsigned *len)
|
||||
{
|
||||
if (isReading()) return nullptr;
|
||||
EndObject();
|
||||
if (len != nullptr)
|
||||
{
|
||||
*len = (unsigned)w->mOutString.GetSize();
|
||||
|
@ -674,6 +692,7 @@ FCompressedBuffer FSerializer::GetCompressedOutput()
|
|||
{
|
||||
if (isReading()) return{ 0,0,0,0,nullptr };
|
||||
FCompressedBuffer buff;
|
||||
EndObject();
|
||||
buff.mSize = (unsigned)w->mOutString.GetSize();
|
||||
buff.mZipFlags = 0;
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ public:
|
|||
FSerializer &Terrain(const char *key, int &terrain, int *def = nullptr);
|
||||
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 &AddString(const char *key, const char *charptr);
|
||||
FSerializer &ScriptNum(const char *key, int &num);
|
||||
bool isReading() const
|
||||
{
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
#include "r_sky.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "m_crc32.h"
|
||||
#include "farchive.h"
|
||||
#include "serializer.h"
|
||||
|
||||
CVAR(Int, savestatistics, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR(String, statfile, "zdoomstat.txt", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
@ -87,7 +87,7 @@ struct OneLevel
|
|||
int totalkills, killcount;
|
||||
int totalsecrets, secretcount;
|
||||
int leveltime;
|
||||
char levelname[9];
|
||||
FString Levelname;
|
||||
};
|
||||
|
||||
// Current game's statistics
|
||||
|
@ -408,13 +408,12 @@ static void StoreLevelStats()
|
|||
{
|
||||
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())
|
||||
{
|
||||
LevelData.Reserve(1);
|
||||
strncpy(LevelData[i].levelname, level.MapName, 8);
|
||||
LevelData[i].levelname[8] = 0;
|
||||
LevelData[i].Levelname = level.MapName;
|
||||
}
|
||||
LevelData[i].totalkills = level.total_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++)
|
||||
{
|
||||
FString lsection = LevelData[i].levelname;
|
||||
FString lsection = LevelData[i].Levelname;
|
||||
lsection.ToUpper();
|
||||
infostring.Format("%4d/%4d, %3d/%3d",
|
||||
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;
|
||||
int i = LevelData.Size();
|
||||
|
||||
arc << i;
|
||||
|
||||
if (arc.IsLoading())
|
||||
if (arc.BeginObject("statistics"))
|
||||
{
|
||||
arc << startlevel;
|
||||
StartEpisode = NULL;
|
||||
for(unsigned int j=0;j<AllEpisodes.Size();j++)
|
||||
if (arc.isReading())
|
||||
{
|
||||
if (!AllEpisodes[j].mEpisodeMap.CompareNoCase(startlevel))
|
||||
arc("startlevel", startlevel);
|
||||
StartEpisode = NULL;
|
||||
for (unsigned int j = 0; j < AllEpisodes.Size(); j++)
|
||||
{
|
||||
StartEpisode = &AllEpisodes[j];
|
||||
break;
|
||||
if (!AllEpisodes[j].mEpisodeMap.CompareNoCase(startlevel))
|
||||
{
|
||||
StartEpisode = &AllEpisodes[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
LevelData.Resize(i);
|
||||
}
|
||||
LevelData.Resize(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (StartEpisode != NULL) startlevel = StartEpisode->mEpisodeMap;
|
||||
arc << startlevel;
|
||||
}
|
||||
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());
|
||||
else
|
||||
{
|
||||
if (StartEpisode != NULL) startlevel = StartEpisode->mEpisodeMap;
|
||||
arc("startlevel", startlevel);
|
||||
}
|
||||
arc("levels", LevelData);
|
||||
arc.EndObject();
|
||||
}
|
||||
}
|
||||
|
||||
#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];
|
||||
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);
|
||||
}
|
||||
return compose;
|
||||
|
|
|
@ -49,9 +49,6 @@
|
|||
|
||||
#include "m_alloc.h"
|
||||
|
||||
class FArchive;
|
||||
|
||||
|
||||
template<typename T> class TIterator
|
||||
{
|
||||
public:
|
||||
|
@ -83,8 +80,6 @@ struct FArray
|
|||
template <class T, class TT=T>
|
||||
class TArray
|
||||
{
|
||||
template<class U, class UU> friend FArchive &operator<< (FArchive &arc, TArray<U,UU> &self);
|
||||
|
||||
public:
|
||||
|
||||
typedef TIterator<T> iterator;
|
||||
|
|
|
@ -9,7 +9,6 @@ struct FRemapTable;
|
|||
struct FCopyInfo;
|
||||
class FScanner;
|
||||
class PClassInventory;
|
||||
class FArchive;
|
||||
|
||||
// Texture IDs
|
||||
class FTextureManager;
|
||||
|
@ -21,8 +20,6 @@ public:
|
|||
FNullTextureID() : FTextureID(0) {}
|
||||
};
|
||||
|
||||
FArchive &operator<< (FArchive &arc, FTextureID &tex);
|
||||
|
||||
//
|
||||
// Animating textures and planes
|
||||
//
|
||||
|
|
|
@ -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
|
||||
// still needed as reference.
|
||||
FCrap &FCrap::ReadObject(DObject* &obj, PClass *wanttype)
|
||||
|
@ -181,3 +161,63 @@ FCrap &FCrap::ReadObject(DObject* &obj, PClass *wanttype)
|
|||
}
|
||||
#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
|
||||
|
|
Loading…
Reference in a new issue