mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-15 16:51:31 +00:00
- allow the compact and pretty writers for JSON to coexist by wrapping the whole stuff into another class that calls the proper one as needed. Due to the implementation it is not possible to decide at run time how this should behave so there have to be two different objects for either mode.
- savegame code handles new format.
This commit is contained in:
parent
ac3c00883d
commit
88c27e2cc0
12 changed files with 423 additions and 292 deletions
|
@ -117,6 +117,7 @@ void STAT_Serialize(FSerializer &file);
|
|||
bool WriteZip(const char *filename, TArray<FString> &filenames, TArray<FCompressedBuffer> &content);
|
||||
|
||||
FIntCVar gameskill ("skill", 2, CVAR_SERVERINFO|CVAR_LATCH);
|
||||
CVAR(Bool, save_formatted, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // use formatted JSON for saves (more readable but a larger files and a bit slower.
|
||||
CVAR (Int, deathmatch, 0, CVAR_SERVERINFO|CVAR_LATCH);
|
||||
CVAR (Bool, chasedemo, false, 0);
|
||||
CVAR (Bool, storesavepic, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
@ -1778,7 +1779,7 @@ void G_LoadGame (const char* name, bool hidecon)
|
|||
}
|
||||
}
|
||||
|
||||
static bool CheckSingleWad (char *name, bool &printRequires, bool printwarn)
|
||||
static bool CheckSingleWad (const char *name, bool &printRequires, bool printwarn)
|
||||
{
|
||||
if (name == NULL)
|
||||
{
|
||||
|
@ -1798,22 +1799,20 @@ static bool CheckSingleWad (char *name, bool &printRequires, bool printwarn)
|
|||
}
|
||||
}
|
||||
printRequires = true;
|
||||
delete[] name;
|
||||
return false;
|
||||
}
|
||||
delete[] name;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return false if not all the needed wads have been loaded.
|
||||
bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn)
|
||||
bool G_CheckSaveGameWads (FSerializer &arc, bool printwarn)
|
||||
{
|
||||
char *text;
|
||||
bool printRequires = false;
|
||||
FString text;
|
||||
|
||||
text = M_GetPNGText (png, "Game WAD");
|
||||
arc("Game WAD", text);
|
||||
CheckSingleWad (text, printRequires, printwarn);
|
||||
text = M_GetPNGText (png, "Map WAD");
|
||||
arc("Map WAD", text);
|
||||
CheckSingleWad (text, printRequires, printwarn);
|
||||
|
||||
if (printRequires)
|
||||
|
@ -2195,8 +2194,8 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
|
|||
FSerializer savegameinfo; // this is for displayable info about the savegame
|
||||
FSerializer savegameglobals; // and this for non-level related info that must be saved.
|
||||
|
||||
savegameinfo.OpenWriter();
|
||||
savegameglobals.OpenWriter();
|
||||
savegameinfo.OpenWriter(true);
|
||||
savegameglobals.OpenWriter(save_formatted);
|
||||
|
||||
SaveVersion = SAVEVER;
|
||||
PutSavePic(&savepic, SAVEPICWIDTH, SAVEPICHEIGHT);
|
||||
|
@ -2267,16 +2266,16 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
|
|||
delete[] savegame_content[1].mBuffer;
|
||||
delete[] savegame_content[2].mBuffer;
|
||||
|
||||
// Check whether the file is ok. (todo when new format is ready)
|
||||
bool success = true;
|
||||
if (success)
|
||||
// Check whether the file is ok by trying to open it.
|
||||
FResourceFile *test = FResourceFile::OpenResourceFile(filename, nullptr, true);
|
||||
if (test != nullptr)
|
||||
{
|
||||
delete test;
|
||||
if (longsavemessages) Printf ("%s (%s)\n", GStrings("GGSAVED"), filename.GetChars());
|
||||
else Printf ("%s\n", GStrings("GGSAVED"));
|
||||
}
|
||||
else Printf(PRINT_HIGH, "Save failed\n");
|
||||
|
||||
FResourceFile *test = FResourceFile::OpenResourceFile(filename, nullptr);
|
||||
|
||||
BackupSaveName = filename;
|
||||
|
||||
|
|
|
@ -68,8 +68,8 @@ void G_ScreenShot (char *filename);
|
|||
|
||||
FString G_BuildSaveName (const char *prefix, int slot);
|
||||
|
||||
struct PNGHandle;
|
||||
bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn);
|
||||
class FSerializer;
|
||||
bool G_CheckSaveGameWads (FSerializer &arc, bool printwarn);
|
||||
|
||||
enum EFinishLevelType
|
||||
{
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
void STAT_StartNewGame(const char *lev);
|
||||
void STAT_ChangeLevel(const char *newl);
|
||||
|
||||
|
||||
EXTERN_CVAR(Bool, save_formatted)
|
||||
EXTERN_CVAR (Float, sv_gravity)
|
||||
EXTERN_CVAR (Float, sv_aircontrol)
|
||||
EXTERN_CVAR (Int, disableautosave)
|
||||
|
@ -1489,7 +1489,7 @@ void G_SnapshotLevel ()
|
|||
{
|
||||
FSerializer arc;
|
||||
|
||||
if (arc.OpenWriter())
|
||||
if (arc.OpenWriter(save_formatted))
|
||||
{
|
||||
SaveVersion = SAVEVER;
|
||||
G_SerializeLevel(arc, false);
|
||||
|
|
30
src/json.cpp
30
src/json.cpp
|
@ -37,33 +37,3 @@ void DThinker::SerializeThinkers(FSerializer &arc, bool hubLoad)
|
|||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void G_SerializeLevel(FSerializer &arc, bool);
|
||||
|
||||
CCMD(writejson)
|
||||
{
|
||||
DWORD t = I_MSTime();
|
||||
FSerializer arc;
|
||||
arc.OpenWriter();
|
||||
G_SerializeLevel(arc, false);
|
||||
arc.WriteObjects();
|
||||
DWORD tt = I_MSTime();
|
||||
Printf("JSON generation took %d ms\n", tt - t);
|
||||
FILE *f = fopen("out.json", "wb");
|
||||
unsigned siz;
|
||||
const char *str = arc.GetOutput(&siz);
|
||||
fwrite(str, 1, siz, f);
|
||||
fclose(f);
|
||||
/*
|
||||
DWORD ttt = I_MSTime();
|
||||
Printf("JSON save took %d ms\n", ttt - tt);
|
||||
FDocument doc(arc.w->mOutString.GetString(), arc.w->mOutString.GetSize());
|
||||
DWORD tttt = I_MSTime();
|
||||
Printf("JSON parse took %d ms\n", tttt - ttt);
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ PNGHandle::PNGHandle (FILE *file) : File(0), bDeleteFilePtr(true), ChunkPt(0)
|
|||
File = new FileReader(file);
|
||||
}
|
||||
|
||||
PNGHandle::PNGHandle (FileReader *file) : File(file), bDeleteFilePtr(false), ChunkPt(0) {}
|
||||
PNGHandle::PNGHandle (FileReader *file, bool takereader) : File(file), bDeleteFilePtr(takereader), ChunkPt(0) {}
|
||||
PNGHandle::~PNGHandle ()
|
||||
{
|
||||
for (unsigned int i = 0; i < TextChunks.Size(); ++i)
|
||||
|
@ -374,15 +374,14 @@ bool M_GetPNGText (PNGHandle *png, const char *keyword, char *buffer, size_t buf
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
PNGHandle *M_VerifyPNG (FILE *file)
|
||||
PNGHandle *M_VerifyPNG (FileReader *filer, bool takereader)
|
||||
{
|
||||
PNGHandle::Chunk chunk;
|
||||
FileReader *filer;
|
||||
PNGHandle *png;
|
||||
DWORD data[2];
|
||||
bool sawIDAT = false;
|
||||
|
||||
if (fread (&data, 1, 8, file) != 8)
|
||||
if (filer->Read(&data, 8) != 8)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -390,7 +389,7 @@ PNGHandle *M_VerifyPNG (FILE *file)
|
|||
{ // Does not have PNG signature
|
||||
return NULL;
|
||||
}
|
||||
if (fread (&data, 1, 8, file) != 8)
|
||||
if (filer->Read (&data, 8) != 8)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -400,8 +399,7 @@ PNGHandle *M_VerifyPNG (FILE *file)
|
|||
}
|
||||
|
||||
// It looks like a PNG so far, so start creating a PNGHandle for it
|
||||
png = new PNGHandle (file);
|
||||
filer = png->File;
|
||||
png = new PNGHandle (filer, takereader);
|
||||
chunk.ID = data[1];
|
||||
chunk.Offset = 16;
|
||||
chunk.Size = BigLong((unsigned int)data[0]);
|
||||
|
@ -430,7 +428,7 @@ PNGHandle *M_VerifyPNG (FILE *file)
|
|||
sawIDAT = true;
|
||||
}
|
||||
chunk.ID = data[1];
|
||||
chunk.Offset = ftell (file);
|
||||
chunk.Offset = filer->Tell();
|
||||
chunk.Size = BigLong((unsigned int)data[0]);
|
||||
png->Chunks.Push (chunk);
|
||||
|
||||
|
@ -454,6 +452,12 @@ PNGHandle *M_VerifyPNG (FILE *file)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
PNGHandle *M_VerifyPNG(FILE *file)
|
||||
{
|
||||
FileReader *fr = new FileReader(file);
|
||||
return M_VerifyPNG(fr, true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// M_FreePNG
|
||||
|
|
|
@ -80,7 +80,7 @@ struct PNGHandle
|
|||
unsigned int ChunkPt;
|
||||
|
||||
PNGHandle(FILE *file);
|
||||
PNGHandle(FileReader *file);
|
||||
PNGHandle(FileReader *file, bool takereader = false);
|
||||
~PNGHandle();
|
||||
};
|
||||
|
||||
|
@ -88,7 +88,7 @@ struct PNGHandle
|
|||
// the signature, but also checking for the IEND chunk. CRC checking of
|
||||
// each chunk is not done. If it is valid, you get a PNGHandle to pass to
|
||||
// the following functions.
|
||||
PNGHandle *M_VerifyPNG (FileReader *file);
|
||||
PNGHandle *M_VerifyPNG (FileReader *file, bool takereader = false);
|
||||
PNGHandle *M_VerifyPNG (FILE *file);
|
||||
|
||||
// Finds a chunk in a PNG file. The file pointer will be positioned at the
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include "doomstat.h"
|
||||
#include "gi.h"
|
||||
#include "d_gui.h"
|
||||
#include "serializer.h"
|
||||
#include "resourcefiles/resourcefile.h"
|
||||
|
||||
|
||||
|
||||
|
@ -86,6 +88,10 @@ protected:
|
|||
int commentRight;
|
||||
int commentBottom;
|
||||
|
||||
// this needs to be kept in memory so that the texture can access it when it needs to.
|
||||
FileReader *currentSavePic;
|
||||
TArray<char> SavePicData;
|
||||
|
||||
|
||||
static int InsertSaveNode (FSaveGameNode *node);
|
||||
static void ReadSaveStrings ();
|
||||
|
@ -221,103 +227,135 @@ void DLoadSaveMenu::ReadSaveStrings ()
|
|||
{
|
||||
// I_FindName only returns the file's name and not its full path
|
||||
FString filepath = G_BuildSaveName (I_FindName(&c_file), -1);
|
||||
FILE *file = fopen (filepath, "rb");
|
||||
|
||||
if (file != NULL)
|
||||
FResourceFile *savegame = FResourceFile::OpenResourceFile(filepath, nullptr, true, true);
|
||||
if (savegame != nullptr)
|
||||
{
|
||||
PNGHandle *png;
|
||||
char sig[16];
|
||||
char title[SAVESTRINGSIZE+1];
|
||||
bool oldVer = true;
|
||||
bool addIt = false;
|
||||
bool oldVer = false;
|
||||
bool missing = false;
|
||||
|
||||
// ZDoom 1.23 betas 21-33 have the savesig first.
|
||||
// Earlier versions have the savesig second.
|
||||
// Later versions have the savegame encapsulated inside a PNG.
|
||||
//
|
||||
// Old savegame versions are always added to the menu so
|
||||
// the user can easily delete them if desired.
|
||||
|
||||
title[SAVESTRINGSIZE] = 0;
|
||||
|
||||
if (false)//NULL != (png = M_VerifyPNG (file)))
|
||||
FResourceLump *info = savegame->FindLump("info.json");
|
||||
if (info == nullptr)
|
||||
{
|
||||
char *ver = M_GetPNGText (png, "ZDoom Save Version");
|
||||
char *engine = M_GetPNGText (png, "Engine");
|
||||
if (ver != NULL)
|
||||
{
|
||||
if (!M_GetPNGText (png, "Title", title, SAVESTRINGSIZE))
|
||||
{
|
||||
strncpy (title, I_FindName(&c_file), SAVESTRINGSIZE);
|
||||
}
|
||||
if (strncmp (ver, "SAVESIG", 9) == 0 &&
|
||||
atoi (ver+9) >= MINSAVEVER &&
|
||||
engine != NULL)
|
||||
{
|
||||
// Was saved with a compatible ZDoom version,
|
||||
// so check if it's for the current game.
|
||||
// If it is, add it. Otherwise, ignore it.
|
||||
char *iwad = M_GetPNGText (png, "Game WAD");
|
||||
if (iwad != NULL)
|
||||
{
|
||||
if (stricmp (iwad, Wads.GetWadName (FWadCollection::IWAD_FILENUM)) == 0)
|
||||
{
|
||||
addIt = true;
|
||||
oldVer = false;
|
||||
missing = !G_CheckSaveGameWads (png, false);
|
||||
}
|
||||
delete[] iwad;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // An old version
|
||||
addIt = true;
|
||||
}
|
||||
delete[] ver;
|
||||
}
|
||||
if (engine != NULL)
|
||||
{
|
||||
delete[] engine;
|
||||
}
|
||||
delete png;
|
||||
// savegame info not found. This is not a savegame so leave it alone.
|
||||
delete savegame;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
void *data = info->CacheLump();
|
||||
FSerializer arc;
|
||||
if (arc.OpenReader((const char *)data, info->LumpSize, true))
|
||||
{
|
||||
fseek (file, 0, SEEK_SET);
|
||||
if (fread (sig, 1, 16, file) == 16)
|
||||
int savever = 0;
|
||||
FString engine;
|
||||
FString iwad;
|
||||
FString title;
|
||||
|
||||
arc("Save Version", savever);
|
||||
arc("Engine", engine);
|
||||
arc("Game WAD", iwad);
|
||||
arc("Title", title);
|
||||
|
||||
if (engine.Compare(GAMESIG) != 0 || savever > SAVEVER)
|
||||
{
|
||||
|
||||
if (strncmp (sig, "ZDOOMSAVE", 9) == 0)
|
||||
{
|
||||
if (fread (title, 1, SAVESTRINGSIZE, file) == SAVESTRINGSIZE)
|
||||
{
|
||||
addIt = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (title, sig, 16);
|
||||
if (fread (title + 16, 1, SAVESTRINGSIZE-16, file) == SAVESTRINGSIZE-16 &&
|
||||
fread (sig, 1, 16, file) == 16 &&
|
||||
strncmp (sig, "ZDOOMSAVE", 9) == 0)
|
||||
{
|
||||
addIt = true;
|
||||
}
|
||||
}
|
||||
// different engine or newer version:
|
||||
// not our business. Leave it alone.
|
||||
delete savegame;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (savever < MINSAVEVER)
|
||||
{
|
||||
// old, incompatible savegame. List as not usable.
|
||||
oldVer = true;
|
||||
}
|
||||
else if (iwad.CompareNoCase(Wads.GetWadName(FWadCollection::IWAD_FILENUM)) == 0)
|
||||
{
|
||||
missing = !G_CheckSaveGameWads(arc, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (addIt)
|
||||
{
|
||||
FSaveGameNode *node = new FSaveGameNode;
|
||||
node->Filename = filepath;
|
||||
node->bOldVersion = oldVer;
|
||||
node->bMissingWads = missing;
|
||||
memcpy (node->Title, title, SAVESTRINGSIZE);
|
||||
InsertSaveNode (node);
|
||||
strncpy(node->Title, title.GetChars(), SAVESTRINGSIZE);
|
||||
InsertSaveNode(node);
|
||||
delete savegame;
|
||||
}
|
||||
|
||||
}
|
||||
else // check for old formats.
|
||||
{
|
||||
FILE *file = fopen (filepath, "rb");
|
||||
if (file != NULL)
|
||||
{
|
||||
PNGHandle *png;
|
||||
char sig[16];
|
||||
char title[SAVESTRINGSIZE+1];
|
||||
bool oldVer = true;
|
||||
bool addIt = false;
|
||||
bool missing = false;
|
||||
|
||||
// ZDoom 1.23 betas 21-33 have the savesig first.
|
||||
// Earlier versions have the savesig second.
|
||||
// Later versions have the savegame encapsulated inside a PNG.
|
||||
//
|
||||
// Old savegame versions are always added to the menu so
|
||||
// the user can easily delete them if desired.
|
||||
|
||||
title[SAVESTRINGSIZE] = 0;
|
||||
|
||||
|
||||
if (NULL != (png = M_VerifyPNG (file)))
|
||||
{
|
||||
char *ver = M_GetPNGText (png, "ZDoom Save Version");
|
||||
if (ver != NULL)
|
||||
{
|
||||
// An old version
|
||||
if (!M_GetPNGText(png, "Title", title, SAVESTRINGSIZE))
|
||||
{
|
||||
strncpy(title, I_FindName(&c_file), SAVESTRINGSIZE);
|
||||
}
|
||||
addIt = true;
|
||||
delete[] ver;
|
||||
}
|
||||
delete png;
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek (file, 0, SEEK_SET);
|
||||
if (fread (sig, 1, 16, file) == 16)
|
||||
{
|
||||
|
||||
if (strncmp (sig, "ZDOOMSAVE", 9) == 0)
|
||||
{
|
||||
if (fread (title, 1, SAVESTRINGSIZE, file) == SAVESTRINGSIZE)
|
||||
{
|
||||
addIt = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (title, sig, 16);
|
||||
if (fread (title + 16, 1, SAVESTRINGSIZE-16, file) == SAVESTRINGSIZE-16 &&
|
||||
fread (sig, 1, 16, file) == 16 &&
|
||||
strncmp (sig, "ZDOOMSAVE", 9) == 0)
|
||||
{
|
||||
addIt = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (addIt)
|
||||
{
|
||||
FSaveGameNode *node = new FSaveGameNode;
|
||||
node->Filename = filepath;
|
||||
node->bOldVersion = true;
|
||||
node->bMissingWads = false;
|
||||
memcpy (node->Title, title, SAVESTRINGSIZE);
|
||||
InsertSaveNode (node);
|
||||
}
|
||||
fclose (file);
|
||||
}
|
||||
fclose (file);
|
||||
}
|
||||
} while (I_FindNext (filefirst, &c_file) == 0);
|
||||
I_FindClose (filefirst);
|
||||
|
@ -407,6 +445,7 @@ DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc)
|
|||
listboxHeight = listboxRows * rowHeight + 1;
|
||||
listboxRight = listboxLeft + listboxWidth;
|
||||
listboxBottom = listboxTop + listboxHeight;
|
||||
currentSavePic = nullptr;
|
||||
|
||||
commentLeft = savepicLeft;
|
||||
commentTop = savepicTop + savepicHeight + 16;
|
||||
|
@ -418,6 +457,8 @@ DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc)
|
|||
|
||||
void DLoadSaveMenu::Destroy()
|
||||
{
|
||||
if (currentSavePic != nullptr) delete currentSavePic;
|
||||
currentSavePic = nullptr;
|
||||
ClearSaveStuff ();
|
||||
}
|
||||
|
||||
|
@ -429,17 +470,23 @@ void DLoadSaveMenu::Destroy()
|
|||
|
||||
void DLoadSaveMenu::UnloadSaveData ()
|
||||
{
|
||||
if (SavePic != NULL)
|
||||
if (SavePic != nullptr)
|
||||
{
|
||||
delete SavePic;
|
||||
}
|
||||
if (SaveComment != NULL)
|
||||
if (SaveComment != nullptr)
|
||||
{
|
||||
V_FreeBrokenLines (SaveComment);
|
||||
}
|
||||
if (currentSavePic != nullptr)
|
||||
{
|
||||
delete currentSavePic;
|
||||
}
|
||||
|
||||
SavePic = NULL;
|
||||
SaveComment = NULL;
|
||||
SavePic = nullptr;
|
||||
SaveComment = nullptr;
|
||||
currentSavePic = nullptr;
|
||||
SavePicData.Clear();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -465,8 +512,7 @@ void DLoadSaveMenu::ClearSaveStuff ()
|
|||
|
||||
void DLoadSaveMenu::ExtractSaveData (int index)
|
||||
{
|
||||
FILE *file;
|
||||
PNGHandle *png;
|
||||
FResourceFile *resf;
|
||||
FSaveGameNode *node;
|
||||
|
||||
UnloadSaveData ();
|
||||
|
@ -475,66 +521,61 @@ void DLoadSaveMenu::ExtractSaveData (int index)
|
|||
(node = SaveGames[index]) &&
|
||||
!node->Filename.IsEmpty() &&
|
||||
!node->bOldVersion &&
|
||||
(file = fopen (node->Filename.GetChars(), "rb")) != NULL)
|
||||
(resf = FResourceFile::OpenResourceFile(node->Filename.GetChars(), nullptr, true)) != nullptr)
|
||||
{
|
||||
if (NULL != (png = M_VerifyPNG (file)))
|
||||
FResourceLump *info = resf->FindLump("info.json");
|
||||
if (info == nullptr)
|
||||
{
|
||||
char *time, *pcomment, *comment;
|
||||
size_t commentlen, totallen, timelen;
|
||||
// this should not happen because the file has already been verified.
|
||||
return;
|
||||
}
|
||||
void *data = info->CacheLump();
|
||||
FSerializer arc;
|
||||
if (arc.OpenReader((const char *)data, info->LumpSize, true))
|
||||
{
|
||||
FString time, pcomment, comment;
|
||||
|
||||
// Extract comment
|
||||
time = M_GetPNGText (png, "Creation Time");
|
||||
pcomment = M_GetPNGText (png, "Comment");
|
||||
if (pcomment != NULL)
|
||||
{
|
||||
commentlen = strlen (pcomment);
|
||||
}
|
||||
else
|
||||
{
|
||||
commentlen = 0;
|
||||
}
|
||||
if (time != NULL)
|
||||
{
|
||||
timelen = strlen (time);
|
||||
totallen = timelen + commentlen + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
timelen = 0;
|
||||
totallen = commentlen + 1;
|
||||
}
|
||||
if (totallen != 0)
|
||||
{
|
||||
comment = new char[totallen];
|
||||
arc("Creation Time", time);
|
||||
arc("Comment", pcomment);
|
||||
|
||||
if (timelen)
|
||||
{
|
||||
memcpy (comment, time, timelen);
|
||||
comment[timelen] = '\n';
|
||||
comment[timelen+1] = '\n';
|
||||
timelen += 2;
|
||||
}
|
||||
if (commentlen)
|
||||
{
|
||||
memcpy (comment + timelen, pcomment, commentlen);
|
||||
}
|
||||
comment[timelen+commentlen] = 0;
|
||||
SaveComment = V_BreakLines (SmallFont, 216*screen->GetWidth()/640/CleanXfac, comment);
|
||||
delete[] comment;
|
||||
delete[] time;
|
||||
delete[] pcomment;
|
||||
}
|
||||
comment = time;
|
||||
if (time.Len() > 0) comment += "\n\n";
|
||||
comment += pcomment;
|
||||
|
||||
SaveComment = V_BreakLines (SmallFont, 216*screen->GetWidth()/640/CleanXfac, comment.GetChars());
|
||||
|
||||
// Extract pic
|
||||
SavePic = PNGTexture_CreateFromFile(png, node->Filename);
|
||||
delete png;
|
||||
if (SavePic->GetWidth() == 1 && SavePic->GetHeight() == 1)
|
||||
FResourceLump *pic = resf->FindLump("savepic.png");
|
||||
if (pic != nullptr)
|
||||
{
|
||||
delete SavePic;
|
||||
SavePic = NULL;
|
||||
FileReader *reader = pic->NewReader();
|
||||
if (reader != nullptr)
|
||||
{
|
||||
// copy to a memory buffer which gets accessed through a memory reader and PNGHandle.
|
||||
// We cannot use the actual lump as backing for the texture because that requires keeping the
|
||||
// savegame file open.
|
||||
SavePicData.Resize(pic->LumpSize);
|
||||
reader->Read(&SavePicData[0], pic->LumpSize);
|
||||
reader = new MemoryReader(&SavePicData[0], SavePicData.Size());
|
||||
PNGHandle *png = M_VerifyPNG(reader);
|
||||
if (png != nullptr)
|
||||
{
|
||||
SavePic = PNGTexture_CreateFromFile(png, node->Filename);
|
||||
currentSavePic = reader; // must be kept so that the texture can read from it.
|
||||
delete png;
|
||||
if (SavePic->GetWidth() == 1 && SavePic->GetHeight() == 1)
|
||||
{
|
||||
delete SavePic;
|
||||
SavePic = nullptr;
|
||||
delete currentSavePic;
|
||||
currentSavePic = nullptr;
|
||||
SavePicData.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose (file);
|
||||
delete resf;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ FResourceFile *CheckDir(const char *filename, FileReader *file, bool quiet);
|
|||
|
||||
static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckLump };
|
||||
|
||||
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader *file, bool quiet)
|
||||
FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader *file, bool quiet, bool containeronly)
|
||||
{
|
||||
if (file == NULL)
|
||||
{
|
||||
|
@ -283,7 +283,7 @@ FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
for(size_t i = 0; i < countof(funcs); i++)
|
||||
for(size_t i = 0; i < countof(funcs) - containeronly; i++)
|
||||
{
|
||||
FResourceFile *resfile = funcs[i](filename, file, quiet);
|
||||
if (resfile != NULL) return resfile;
|
||||
|
@ -560,6 +560,24 @@ void FResourceFile::FindStrifeTeaserVoices ()
|
|||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Finds a lump by a given name. Used for savegames
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FResourceLump *FResourceFile::FindLump(const char *name)
|
||||
{
|
||||
for (unsigned i = 0; i < NumLumps; i++)
|
||||
{
|
||||
FResourceLump *lump = GetLump(i);
|
||||
if (!stricmp(name, lump->FullName))
|
||||
{
|
||||
return lump;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -77,7 +77,7 @@ private:
|
|||
void JunkLeftoverFilters(void *lumps, size_t lumpsize, DWORD max);
|
||||
|
||||
public:
|
||||
static FResourceFile *OpenResourceFile(const char *filename, FileReader *file, bool quiet = false);
|
||||
static FResourceFile *OpenResourceFile(const char *filename, FileReader *file, bool quiet = false, bool containeronly = false);
|
||||
static FResourceFile *OpenDirectory(const char *filename, bool quiet = false);
|
||||
virtual ~FResourceFile();
|
||||
FileReader *GetReader() const { return Reader; }
|
||||
|
@ -88,6 +88,7 @@ public:
|
|||
virtual void FindStrifeTeaserVoices ();
|
||||
virtual bool Open(bool quiet) = 0;
|
||||
virtual FResourceLump *GetLump(int no) = 0;
|
||||
FResourceLump *FindLump(const char *name);
|
||||
};
|
||||
|
||||
struct FUncompressedLump : public FResourceLump
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1
|
||||
#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseFullPrecisionFlag
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define PRETTY
|
||||
#endif
|
||||
|
||||
#include "rapidjson/rapidjson.h"
|
||||
#include "rapidjson/writer.h"
|
||||
#include "rapidjson/prettywriter.h"
|
||||
|
@ -69,26 +65,126 @@ struct FJSONObject
|
|||
|
||||
struct FWriter
|
||||
{
|
||||
// Since this is done by template parameters, we'd have to template the entire serializer to allow this switch at run time. Argh!
|
||||
#ifndef PRETTY
|
||||
typedef rapidjson::Writer<rapidjson::StringBuffer, rapidjson::ASCII<> > Writer;
|
||||
#else
|
||||
typedef rapidjson::PrettyWriter<rapidjson::StringBuffer, rapidjson::ASCII<> > Writer;
|
||||
#endif
|
||||
typedef rapidjson::PrettyWriter<rapidjson::StringBuffer, rapidjson::ASCII<> > PrettyWriter;
|
||||
|
||||
Writer mWriter;
|
||||
Writer *mWriter1;
|
||||
PrettyWriter *mWriter2;
|
||||
TArray<bool> mInObject;
|
||||
rapidjson::StringBuffer mOutString;
|
||||
TArray<DObject *> mDObjects;
|
||||
TMap<DObject *, int> mObjectMap;
|
||||
|
||||
FWriter() : mWriter(mOutString)
|
||||
{}
|
||||
FWriter(bool pretty)
|
||||
{
|
||||
if (!pretty)
|
||||
{
|
||||
mWriter1 = new Writer(mOutString);
|
||||
mWriter2 = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
mWriter1 = nullptr;
|
||||
mWriter2 = new PrettyWriter(mOutString);
|
||||
}
|
||||
}
|
||||
|
||||
~FWriter()
|
||||
{
|
||||
if (mWriter1) delete mWriter1;
|
||||
if (mWriter2) delete mWriter2;
|
||||
}
|
||||
|
||||
|
||||
bool inObject() const
|
||||
{
|
||||
return mInObject.Size() > 0 && mInObject.Last();
|
||||
}
|
||||
|
||||
void StartObject()
|
||||
{
|
||||
if (mWriter1) mWriter1->StartObject();
|
||||
else if (mWriter2) mWriter2->StartObject();
|
||||
}
|
||||
|
||||
void EndObject()
|
||||
{
|
||||
if (mWriter1) mWriter1->EndObject();
|
||||
else if (mWriter2) mWriter2->EndObject();
|
||||
}
|
||||
|
||||
void StartArray()
|
||||
{
|
||||
if (mWriter1) mWriter1->StartArray();
|
||||
else if (mWriter2) mWriter2->StartArray();
|
||||
}
|
||||
|
||||
void EndArray()
|
||||
{
|
||||
if (mWriter1) mWriter1->EndArray();
|
||||
else if (mWriter2) mWriter2->EndArray();
|
||||
}
|
||||
|
||||
void Key(const char *k)
|
||||
{
|
||||
if (mWriter1) mWriter1->Key(k);
|
||||
else if (mWriter2) mWriter2->Key(k);
|
||||
}
|
||||
|
||||
void Null()
|
||||
{
|
||||
if (mWriter1) mWriter1->Null();
|
||||
else if (mWriter2) mWriter2->Null();
|
||||
}
|
||||
|
||||
void String(const char *k)
|
||||
{
|
||||
if (mWriter1) mWriter1->String(k);
|
||||
else if (mWriter2) mWriter2->String(k);
|
||||
}
|
||||
|
||||
void String(const char *k, int size)
|
||||
{
|
||||
if (mWriter1) mWriter1->String(k, size);
|
||||
else if (mWriter2) mWriter2->String(k, size);
|
||||
}
|
||||
|
||||
void Bool(bool k)
|
||||
{
|
||||
if (mWriter1) mWriter1->Bool(k);
|
||||
else if (mWriter2) mWriter2->Bool(k);
|
||||
}
|
||||
|
||||
void Int(int32_t k)
|
||||
{
|
||||
if (mWriter1) mWriter1->Int(k);
|
||||
else if (mWriter2) mWriter2->Int(k);
|
||||
}
|
||||
|
||||
void Int64(int64_t k)
|
||||
{
|
||||
if (mWriter1) mWriter1->Int64(k);
|
||||
else if (mWriter2) mWriter2->Int64(k);
|
||||
}
|
||||
|
||||
void Uint(uint32_t k)
|
||||
{
|
||||
if (mWriter1) mWriter1->Uint(k);
|
||||
else if (mWriter2) mWriter2->Uint(k);
|
||||
}
|
||||
|
||||
void Uint64(int64_t k)
|
||||
{
|
||||
if (mWriter1) mWriter1->Uint64(k);
|
||||
else if (mWriter2) mWriter2->Uint64(k);
|
||||
}
|
||||
|
||||
void Double(double k)
|
||||
{
|
||||
if (mWriter1) mWriter1->Double(k);
|
||||
else if (mWriter2) mWriter2->Double(k);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -100,14 +196,13 @@ struct FWriter
|
|||
struct FReader
|
||||
{
|
||||
TArray<FJSONObject> mObjects;
|
||||
rapidjson::Value mDocObj; // just because RapidJSON is stupid and does not allow direct access to what's in the document.
|
||||
rapidjson::Document mDoc;
|
||||
|
||||
FReader(const char *buffer, size_t length)
|
||||
FReader(const char *buffer, size_t length, bool randomaccess)
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(buffer, length);
|
||||
mDocObj = doc.GetObject();
|
||||
mObjects.Push(FJSONObject(&mDocObj)); // Todo: Decide if this should be made random access...
|
||||
mDoc.Parse(buffer, length);
|
||||
mObjects.Push(FJSONObject(&mDoc, randomaccess));
|
||||
}
|
||||
|
||||
rapidjson::Value *FindKey(const char *key)
|
||||
|
@ -149,12 +244,12 @@ struct FReader
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FSerializer::OpenWriter(bool randomaccess)
|
||||
bool FSerializer::OpenWriter(bool pretty)
|
||||
{
|
||||
if (w != nullptr || r != nullptr) return false;
|
||||
w = new FWriter;
|
||||
w = new FWriter(pretty);
|
||||
|
||||
BeginObject(nullptr, randomaccess);
|
||||
BeginObject(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -164,10 +259,10 @@ bool FSerializer::OpenWriter(bool randomaccess)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FSerializer::OpenReader(const char *buffer, size_t length)
|
||||
bool FSerializer::OpenReader(const char *buffer, size_t length, bool randomaccess)
|
||||
{
|
||||
if (w != nullptr || r != nullptr) return false;
|
||||
r = new FReader(buffer, length);
|
||||
r = new FReader(buffer, length, randomaccess);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -177,21 +272,21 @@ bool FSerializer::OpenReader(const char *buffer, size_t length)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FSerializer::OpenReader(FCompressedBuffer *input)
|
||||
bool FSerializer::OpenReader(FCompressedBuffer *input, bool randomaccess)
|
||||
{
|
||||
if (input->mSize <= 0 || input->mBuffer == nullptr) return false;
|
||||
if (w != nullptr || r != nullptr) return false;
|
||||
|
||||
if (input->mMethod == METHOD_STORED)
|
||||
{
|
||||
r = new FReader((char*)input->mBuffer, input->mSize);
|
||||
r = new FReader((char*)input->mBuffer, input->mSize, randomaccess);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *unpacked = new char[input->mSize];
|
||||
input->Decompress(unpacked);
|
||||
r = new FReader(unpacked, input->mSize);
|
||||
r = new FReader(unpacked, input->mSize, randomaccess);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -260,7 +355,7 @@ void FSerializer::WriteKey(const char *key)
|
|||
{
|
||||
I_Error("missing element name");
|
||||
}
|
||||
w->mWriter.Key(key);
|
||||
w->Key(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +370,7 @@ bool FSerializer::BeginObject(const char *name, bool randomaccess)
|
|||
if (isWriting())
|
||||
{
|
||||
WriteKey(name);
|
||||
w->mWriter.StartObject();
|
||||
w->StartObject();
|
||||
w->mInObject.Push(true);
|
||||
}
|
||||
else
|
||||
|
@ -312,7 +407,7 @@ void FSerializer::EndObject()
|
|||
{
|
||||
if (w->inObject())
|
||||
{
|
||||
w->mWriter.EndObject();
|
||||
w->EndObject();
|
||||
w->mInObject.Pop();
|
||||
}
|
||||
else
|
||||
|
@ -337,7 +432,7 @@ bool FSerializer::BeginArray(const char *name)
|
|||
if (isWriting())
|
||||
{
|
||||
WriteKey(name);
|
||||
w->mWriter.StartArray();
|
||||
w->StartArray();
|
||||
w->mInObject.Push(false);
|
||||
}
|
||||
else
|
||||
|
@ -374,7 +469,7 @@ void FSerializer::EndArray()
|
|||
{
|
||||
if (!w->inObject())
|
||||
{
|
||||
w->mWriter.EndArray();
|
||||
w->EndArray();
|
||||
w->mInObject.Pop();
|
||||
}
|
||||
else
|
||||
|
@ -404,19 +499,19 @@ FSerializer &FSerializer::Args(const char *key, int *args, int *defargs, int spe
|
|||
}
|
||||
|
||||
WriteKey(key);
|
||||
w->mWriter.StartArray();
|
||||
w->StartArray();
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
if (i == 0 && args[i] < 0 && P_IsACSSpecial(special))
|
||||
{
|
||||
w->mWriter.String(FName(ENamedName(-args[i])).GetChars());
|
||||
w->String(FName(ENamedName(-args[i])).GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
w->mWriter.Int(args[i]);
|
||||
w->Int(args[i]);
|
||||
}
|
||||
}
|
||||
w->mWriter.EndArray();
|
||||
w->EndArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -465,11 +560,11 @@ FSerializer &FSerializer::ScriptNum(const char *key, int &num)
|
|||
WriteKey(key);
|
||||
if (num < 0)
|
||||
{
|
||||
w->mWriter.String(FName(ENamedName(-num)).GetChars());
|
||||
w->String(FName(ENamedName(-num)).GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
w->mWriter.Int(num);
|
||||
w->Int(num);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -527,7 +622,7 @@ FSerializer &FSerializer::Sprite(const char *key, int32_t &spritenum, int32_t *d
|
|||
{
|
||||
if (w->inObject() && def != nullptr && *def == spritenum) return *this;
|
||||
WriteKey(key);
|
||||
w->mWriter.String(sprites[spritenum].name, 4);
|
||||
w->String(sprites[spritenum].name, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -562,7 +657,7 @@ FSerializer &FSerializer::StringPtr(const char *key, const char *&charptr)
|
|||
if (isWriting())
|
||||
{
|
||||
WriteKey(key);
|
||||
w->mWriter.String(charptr);
|
||||
w->String(charptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -593,7 +688,7 @@ FSerializer &FSerializer::AddString(const char *key, const char *charptr)
|
|||
if (isWriting())
|
||||
{
|
||||
WriteKey(key);
|
||||
w->mWriter.String(charptr);
|
||||
w->String(charptr);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -608,7 +703,7 @@ unsigned FSerializer::GetSize(const char *group)
|
|||
{
|
||||
if (isWriting()) return -1; // we do not know this when writing.
|
||||
|
||||
const rapidjson::Value &val = r->mDocObj[group];
|
||||
const rapidjson::Value &val = r->mDoc[group];
|
||||
if (!val.IsArray()) return -1;
|
||||
return val.Size();
|
||||
}
|
||||
|
@ -645,15 +740,15 @@ void FSerializer::WriteObjects()
|
|||
player_t *player;
|
||||
|
||||
BeginObject(nullptr);
|
||||
w->mWriter.Key("classtype");
|
||||
w->mWriter.String(obj->GetClass()->TypeName.GetChars());
|
||||
w->Key("classtype");
|
||||
w->String(obj->GetClass()->TypeName.GetChars());
|
||||
|
||||
if (obj->IsKindOf(RUNTIME_CLASS(AActor)) &&
|
||||
(player = static_cast<AActor *>(obj)->player) &&
|
||||
player->mo == obj)
|
||||
{
|
||||
w->mWriter.Key("playerindex");
|
||||
w->mWriter.Int(int(player - players));
|
||||
w->Key("playerindex");
|
||||
w->Int(int(player - players));
|
||||
}
|
||||
|
||||
obj->SerializeUserVars(*this);
|
||||
|
@ -755,7 +850,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, bool &value, bool *def
|
|||
if (!arc.w->inObject() || defval == nullptr || value != *defval)
|
||||
{
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.Bool(value);
|
||||
arc.w->Bool(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -789,7 +884,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, int64_t &value, int64_
|
|||
if (!arc.w->inObject() || defval == nullptr || value != *defval)
|
||||
{
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.Int64(value);
|
||||
arc.w->Int64(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -823,7 +918,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, uint64_t &value, uint6
|
|||
if (!arc.w->inObject() || defval == nullptr || value != *defval)
|
||||
{
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.Uint64(value);
|
||||
arc.w->Uint64(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -858,7 +953,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, int32_t &value, int32_
|
|||
if (!arc.w->inObject() || defval == nullptr || value != *defval)
|
||||
{
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.Int(value);
|
||||
arc.w->Int(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -892,7 +987,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, uint32_t &value, uint3
|
|||
if (!arc.w->inObject() || defval == nullptr || value != *defval)
|
||||
{
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.Uint(value);
|
||||
arc.w->Uint(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -968,7 +1063,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, double &value, double
|
|||
if (!arc.w->inObject() || defval == nullptr || value != *defval)
|
||||
{
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.Double(value);
|
||||
arc.w->Double(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1077,14 +1172,14 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe
|
|||
if (!value.Exists())
|
||||
{
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.Null();
|
||||
arc.w->Null();
|
||||
return arc;
|
||||
}
|
||||
if (value.isNull())
|
||||
{
|
||||
// save 'no texture' in a more space saving way
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.Int(0);
|
||||
arc.w->Int(0);
|
||||
return arc;
|
||||
}
|
||||
FTextureID chk = value;
|
||||
|
@ -1101,10 +1196,10 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe
|
|||
name = pic->Name;
|
||||
}
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.StartArray();
|
||||
arc.w->mWriter.String(name);
|
||||
arc.w->mWriter.Int(pic->UseType);
|
||||
arc.w->mWriter.EndArray();
|
||||
arc.w->StartArray();
|
||||
arc.w->String(name);
|
||||
arc.w->Int(pic->UseType);
|
||||
arc.w->EndArray();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1215,7 +1310,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FName &value, FName *d
|
|||
if (!arc.w->inObject() || defval == nullptr || value != *defval)
|
||||
{
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.String(value.GetChars());
|
||||
arc.w->String(value.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1252,11 +1347,11 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FDynamicCol
|
|||
}
|
||||
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.StartArray();
|
||||
arc.w->mWriter.Uint(cm->Color);
|
||||
arc.w->mWriter.Uint(cm->Fade);
|
||||
arc.w->mWriter.Uint(cm->Desaturate);
|
||||
arc.w->mWriter.EndArray();
|
||||
arc.w->StartArray();
|
||||
arc.w->Uint(cm->Color);
|
||||
arc.w->Uint(cm->Fade);
|
||||
arc.w->Uint(cm->Desaturate);
|
||||
arc.w->EndArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1300,8 +1395,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundI
|
|||
{
|
||||
arc.WriteKey(key);
|
||||
const char *sn = (const char*)sid;
|
||||
if (sn != nullptr) arc.w->mWriter.String(sn);
|
||||
else arc.w->mWriter.Null();
|
||||
if (sn != nullptr) arc.w->String(sn);
|
||||
else arc.w->Null();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1342,11 +1437,11 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClassActor
|
|||
arc.WriteKey(key);
|
||||
if (clst == nullptr)
|
||||
{
|
||||
arc.w->mWriter.Null();
|
||||
arc.w->Null();
|
||||
}
|
||||
else
|
||||
{
|
||||
arc.w->mWriter.String(clst->TypeName.GetChars());
|
||||
arc.w->String(clst->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1388,11 +1483,11 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClass *&cl
|
|||
arc.WriteKey(key);
|
||||
if (clst == nullptr)
|
||||
{
|
||||
arc.w->mWriter.Null();
|
||||
arc.w->Null();
|
||||
}
|
||||
else
|
||||
{
|
||||
arc.w->mWriter.String(clst->TypeName.GetChars());
|
||||
arc.w->String(clst->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1436,7 +1531,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState
|
|||
arc.WriteKey(key);
|
||||
if (state == nullptr)
|
||||
{
|
||||
arc.w->mWriter.Null();
|
||||
arc.w->Null();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1444,14 +1539,14 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState
|
|||
|
||||
if (info != NULL)
|
||||
{
|
||||
arc.w->mWriter.StartArray();
|
||||
arc.w->mWriter.String(info->TypeName.GetChars());
|
||||
arc.w->mWriter.Uint((uint32_t)(state - info->OwnedStates));
|
||||
arc.w->mWriter.EndArray();
|
||||
arc.w->StartArray();
|
||||
arc.w->String(info->TypeName.GetChars());
|
||||
arc.w->Uint((uint32_t)(state - info->OwnedStates));
|
||||
arc.w->EndArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
arc.w->mWriter.Null();
|
||||
arc.w->Null();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1507,11 +1602,11 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FStrifeDial
|
|||
arc.WriteKey(key);
|
||||
if (node == nullptr)
|
||||
{
|
||||
arc.w->mWriter.Null();
|
||||
arc.w->Null();
|
||||
}
|
||||
else
|
||||
{
|
||||
arc.w->mWriter.Uint(node->ThisNodeNum);
|
||||
arc.w->Uint(node->ThisNodeNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1560,11 +1655,11 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FString *&p
|
|||
arc.WriteKey(key);
|
||||
if (pstr == nullptr)
|
||||
{
|
||||
arc.w->mWriter.Null();
|
||||
arc.w->Null();
|
||||
}
|
||||
else
|
||||
{
|
||||
arc.w->mWriter.String(pstr->GetChars());
|
||||
arc.w->String(pstr->GetChars());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1604,7 +1699,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FString &pstr, FString
|
|||
if (!arc.w->inObject() || def == nullptr || pstr.Compare(*def) != 0)
|
||||
{
|
||||
arc.WriteKey(key);
|
||||
arc.w->mWriter.String(pstr.GetChars());
|
||||
arc.w->String(pstr.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1645,11 +1740,11 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, char *&pstr
|
|||
arc.WriteKey(key);
|
||||
if (pstr == nullptr)
|
||||
{
|
||||
arc.w->mWriter.Null();
|
||||
arc.w->Null();
|
||||
}
|
||||
else
|
||||
{
|
||||
arc.w->mWriter.String(pstr);
|
||||
arc.w->String(pstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1719,16 +1814,16 @@ FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &value, N
|
|||
switch (value.type)
|
||||
{
|
||||
case NumericValue::NM_signed:
|
||||
arc.w->mWriter.Int64(value.signedval);
|
||||
arc.w->Int64(value.signedval);
|
||||
break;
|
||||
case NumericValue::NM_unsigned:
|
||||
arc.w->mWriter.Uint64(value.unsignedval);
|
||||
arc.w->Uint64(value.unsignedval);
|
||||
break;
|
||||
case NumericValue::NM_float:
|
||||
arc.w->mWriter.Double(value.floatval);
|
||||
arc.w->Double(value.floatval);
|
||||
break;
|
||||
default:
|
||||
arc.w->mWriter.Null();
|
||||
arc.w->Null();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,9 +58,9 @@ public:
|
|||
{
|
||||
Close();
|
||||
}
|
||||
bool OpenWriter(bool randomaccess = true);
|
||||
bool OpenReader(const char *buffer, size_t length);
|
||||
bool OpenReader(FCompressedBuffer *input);
|
||||
bool OpenWriter(bool pretty = true);
|
||||
bool OpenReader(const char *buffer, size_t length, bool randomaccess = false);
|
||||
bool OpenReader(FCompressedBuffer *input, bool randomaccess = false);
|
||||
void Close();
|
||||
bool BeginObject(const char *name, bool randomaccess = false);
|
||||
void EndObject();
|
||||
|
|
|
@ -66,6 +66,7 @@ protected:
|
|||
FString SourceFile;
|
||||
BYTE *Pixels;
|
||||
Span **Spans;
|
||||
FileReader *fr;
|
||||
|
||||
BYTE BitDepth;
|
||||
BYTE ColorType;
|
||||
|
@ -209,6 +210,8 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
|||
DWORD len, id;
|
||||
int i;
|
||||
|
||||
if (lumpnum == -1) fr = &lump;
|
||||
|
||||
UseType = TEX_MiscPatch;
|
||||
LeftOffset = 0;
|
||||
TopOffset = 0;
|
||||
|
@ -462,7 +465,7 @@ void FPNGTexture::MakeTexture ()
|
|||
}
|
||||
else
|
||||
{
|
||||
lump = new FileReader(SourceFile.GetChars());
|
||||
lump = fr;// new FileReader(SourceFile.GetChars());
|
||||
}
|
||||
|
||||
Pixels = new BYTE[Width*Height];
|
||||
|
@ -599,7 +602,7 @@ void FPNGTexture::MakeTexture ()
|
|||
delete[] tempix;
|
||||
}
|
||||
}
|
||||
delete lump;
|
||||
if (lump != fr) delete lump;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -624,7 +627,7 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
}
|
||||
else
|
||||
{
|
||||
lump = new FileReader(SourceFile.GetChars());
|
||||
lump = fr;// new FileReader(SourceFile.GetChars());
|
||||
}
|
||||
|
||||
lump->Seek(33, SEEK_SET);
|
||||
|
@ -683,7 +686,7 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
lump->Read(&len, 4);
|
||||
lump->Read(&id, 4);
|
||||
M_ReadIDAT (lump, Pixels, Width, Height, pixwidth, BitDepth, ColorType, Interlace, BigLong((unsigned int)len));
|
||||
delete lump;
|
||||
if (lump != fr) delete lump;
|
||||
|
||||
switch (ColorType)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue