- started transitioning the savegame writer to the newly added serializer.

Writing info.json done.
This commit is contained in:
Christoph Oelckers 2020-02-23 09:41:12 +01:00
parent 88b6661395
commit a09e195954
4 changed files with 67 additions and 32 deletions

View file

@ -10,6 +10,7 @@ class CompositeSavegameWriter
{ {
FString filename; FString filename;
TDeletingArray<BufferWriter*> subfiles; TDeletingArray<BufferWriter*> subfiles;
TArray<FCompressedBuffer> subbuffers;
TArray<FString> subfilenames; TArray<FString> subfilenames;
TArray<bool> isCompressed; TArray<bool> isCompressed;
@ -17,9 +18,11 @@ class CompositeSavegameWriter
public: public:
void Clear() void Clear()
{ {
for (auto& b : subbuffers) b.Clean();
isCompressed.Clear(); isCompressed.Clear();
subfilenames.Clear(); subfilenames.Clear();
subfiles.DeleteAndClear(); subfiles.DeleteAndClear();
subbuffers.Clear();
filename = ""; filename = "";
} }
void SetFileName(const char* fn) void SetFileName(const char* fn)
@ -35,6 +38,7 @@ public:
assert(subfiles.Size() == 0); // must be written out. assert(subfiles.Size() == 0); // must be written out.
} }
FileWriter& NewElement(const char* filename, bool compress = true); FileWriter& NewElement(const char* filename, bool compress = true);
void AddCompressedElement(const char* filename, FCompressedBuffer& buffer);
bool WriteToFile(); bool WriteToFile();
}; };

View file

@ -46,16 +46,27 @@ bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompress
FileWriter &CompositeSavegameWriter::NewElement(const char *filename, bool compress) FileWriter &CompositeSavegameWriter::NewElement(const char *filename, bool compress)
{ {
FCompressedBuffer b{};
subfilenames.Push(filename); subfilenames.Push(filename);
subbuffers.Push(b);
isCompressed.Push(compress); isCompressed.Push(compress);
auto bwr = new BufferWriter; auto bwr = new BufferWriter;
subfiles.Push(bwr); subfiles.Push(bwr);
return *bwr; return *bwr;
} }
void CompositeSavegameWriter::AddCompressedElement(const char* filename, FCompressedBuffer& buffer)
{
subfilenames.Push(filename);
subbuffers.Push(buffer);
buffer = {};
subfiles.Push(nullptr);
}
FCompressedBuffer CompositeSavegameWriter::CompressElement(BufferWriter *bw, bool compress) FCompressedBuffer CompositeSavegameWriter::CompressElement(BufferWriter *bw, bool compress)
{ {
FCompressedBuffer buff; FCompressedBuffer buff;
auto buffer =bw->GetBuffer(); auto buffer =bw->GetBuffer();
buff.mSize = buffer->Size(); buff.mSize = buffer->Size();
buff.mZipFlags = 0; buff.mZipFlags = 0;
@ -116,7 +127,13 @@ bool CompositeSavegameWriter::WriteToFile()
TArray<FCompressedBuffer> compressed(subfiles.Size(), 1); TArray<FCompressedBuffer> compressed(subfiles.Size(), 1);
for (unsigned i = 0; i < subfiles.Size(); i++) for (unsigned i = 0; i < subfiles.Size(); i++)
{ {
compressed[i] = CompressElement(subfiles[i], isCompressed[i]); if (subfiles[i])
compressed[i] = CompressElement(subfiles[i], isCompressed[i]);
else
{
compressed[i] = subbuffers[i];
subbuffers[i] = {};
}
} }
if (WriteZip(filename, subfilenames, compressed)) if (WriteZip(filename, subfilenames, compressed))

View file

@ -21,7 +21,7 @@ enum ELumpFlags
class FResourceFile; class FResourceFile;
// This holds a compresed Zip entry with all needed info to decompress it. // This holds a compressed Zip entry with all needed info to decompress it.
struct FCompressedBuffer struct FCompressedBuffer
{ {
unsigned mSize; unsigned mSize;

View file

@ -49,6 +49,8 @@
#include "v_video.h" #include "v_video.h"
#include "gamecontrol.h" #include "gamecontrol.h"
#include "m_argv.h" #include "m_argv.h"
#include "serializer.h"
#include "version.h"
static CompositeSavegameWriter savewriter; static CompositeSavegameWriter savewriter;
static FResourceFile *savereader; static FResourceFile *savereader;
@ -78,6 +80,7 @@ bool OpenSaveGameForRead(const char *name)
if (savereader != nullptr) if (savereader != nullptr)
{ {
// Load system-side data from savegames. // Load system-side data from savegames.
ReadStatistics(); ReadStatistics();
SECRET_Load(); SECRET_Load();
@ -107,6 +110,11 @@ FileWriter *WriteSavegameChunk(const char *name)
return &savewriter.NewElement(name); return &savewriter.NewElement(name);
} }
void AddCompressedSavegameChunk(const char* name, FCompressedBuffer& buffer)
{
savewriter.AddCompressedElement(name, buffer);
}
FileReader ReadSavegameChunk(const char *name) FileReader ReadSavegameChunk(const char *name)
{ {
if (!savereader) return FileReader(); if (!savereader) return FileReader();
@ -126,6 +134,8 @@ void FinishSavegameRead()
savereader = nullptr; savereader = nullptr;
} }
CVAR(Bool, save_formatted, true, 0) // should be set to false once the conversion is done
//============================================================================= //=============================================================================
// //
// Creates the savegame and writes all cross-game content. // Creates the savegame and writes all cross-game content.
@ -137,25 +147,31 @@ bool OpenSaveGameForWrite(const char* filename, const char *name)
savewriter.Clear(); savewriter.Clear();
savewriter.SetFileName(filename); savewriter.SetFileName(filename);
sjson_context* ctx = sjson_create_context(0, 0, NULL); FSerializer savegameinfo; // this is for displayable info about the savegame.
if (!ctx) FSerializer savegamesession; // saved game session settings.
{ FSerializer savegameengine; // saved play state.
savewriter.Clear();
return false; savegameinfo.OpenWriter(true);
} savegamesession.OpenWriter(save_formatted);
sjson_node* root = sjson_mkobject(ctx); savegameengine.OpenWriter(save_formatted);
char buf[100];
mysnprintf(buf, countof(buf), GAMENAME " %s", GetVersionString());
auto savesig = gi->GetSaveSig(); auto savesig = gi->GetSaveSig();
sjson_put_int(ctx, root, "Save Version", savesig.currentsavever);
sjson_put_string(ctx, root, "Engine", savesig.savesig);
sjson_put_string(ctx, root, "Game Resource", fileSystem.GetResourceFileName(1));
sjson_put_string(ctx, root, "Map Name", currentLevel->DisplayName());
sjson_put_string(ctx, root, "Creation Time", myasctime());
sjson_put_string(ctx, root, "Title", name);
sjson_put_string(ctx, root, "Map File", currentLevel->fileName);
sjson_put_string(ctx, root, "Map Label", currentLevel->labelName);
auto gs = gi->getStats(); auto gs = gi->getStats();
FStringf timeStr("%02d:%02d", gs.timesecnd / 60, gs.timesecnd % 60); FStringf timeStr("%02d:%02d", gs.timesecnd / 60, gs.timesecnd % 60);
sjson_put_string(ctx, root, "Map Time", timeStr);
savegameinfo.AddString("Software", buf)
("Save Version", savesig.currentsavever)
.AddString("Engine", savesig.savesig)
.AddString("Game Resource", fileSystem.GetResourceFileName(1))
.AddString("Map Name", currentLevel->DisplayName())
.AddString("Creation Time", myasctime())
.AddString("Title", name)
.AddString("Map File", currentLevel->fileName)
.AddString("Map Label", currentLevel->labelName)
.AddString("Map Time", timeStr);
const char *fn = currentLevel->fileName; const char *fn = currentLevel->fileName;
if (*fn == '/') fn++; if (*fn == '/') fn++;
if (strncmp(fn, "file://", 7) != 0) // this only has meaning for non-usermaps if (strncmp(fn, "file://", 7) != 0) // this only has meaning for non-usermaps
@ -163,7 +179,7 @@ bool OpenSaveGameForWrite(const char* filename, const char *name)
auto fileno = fileSystem.FindFile(fn); auto fileno = fileSystem.FindFile(fn);
auto mapfile = fileSystem.GetFileContainer(fileno); auto mapfile = fileSystem.GetFileContainer(fileno);
auto mapcname = fileSystem.GetResourceFileName(mapfile); auto mapcname = fileSystem.GetResourceFileName(mapfile);
if (mapcname) sjson_put_string(ctx, root, "Map Resource", mapcname); if (mapcname) savegameinfo.AddString("Map Resource", mapcname);
else else
{ {
savewriter.Clear(); savewriter.Clear();
@ -171,20 +187,9 @@ bool OpenSaveGameForWrite(const char* filename, const char *name)
} }
} }
char* encoded = sjson_stringify(ctx, root, " "); auto buff = savegameinfo.GetCompressedOutput();
AddCompressedSavegameChunk("info.json", buff);
FileWriter* fil = WriteSavegameChunk("info.json");
if (!fil)
{
sjson_destroy_context(ctx);
savewriter.Clear();
return false;
}
fil->Write(encoded, strlen(encoded));
sjson_free_string(ctx, encoded);
sjson_destroy_context(ctx);
// Handle system-side modules that need to persist data in savegames here, in a central place. // Handle system-side modules that need to persist data in savegames here, in a central place.
SaveStatistics(); SaveStatistics();
@ -265,6 +270,15 @@ static bool G_CheckSaveGameWads (const char *gamegrp, const char *mapgrp, bool p
int G_ValidateSavegame(FileReader &fr, FString *savetitle, bool formenu) int G_ValidateSavegame(FileReader &fr, FString *savetitle, bool formenu)
{ {
#if 0
FSerializer arc(nullptr);
if (!arc.OpenReader((const char*)data, info->LumpSize))
{
LoadGameError("TXT_FAILEDTOREADSG");
return;
}
#endif
auto data = fr.ReadPadded(1); auto data = fr.ReadPadded(1);
sjson_context* ctx = sjson_create_context(0, 0, NULL); sjson_context* ctx = sjson_create_context(0, 0, NULL);