gzdoom/src/json.cpp
Christoph Oelckers 967ed48fd3 - fixing.
2016-09-19 01:48:48 +02:00

595 lines
16 KiB
C++

#include "serializer.h"
#include "r_local.h"
#include "p_setup.h"
#include "c_dispatch.h"
#include "i_system.h"
#include "a_sharedglobal.h"
//==========================================================================
//
//
//
//==========================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, line_t &line, line_t *def)
{
if (arc.BeginObject(key))
{
arc("flags", line.flags, def->flags)
("activation", line.activation, def->activation)
("special", line.special, def->special)
("alpha", line.alpha, def->alpha)
.Args("args", line.args, def->args, line.special)
("portalindex", line.portalindex, def->portalindex)
// no need to store the sidedef references. Unless the map loader is changed they will not change between map loads.
//.Array("sides", line.sidedef, 2)
.EndObject();
}
return arc;
}
//==========================================================================
//
//
//
//==========================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, side_t::part &part, side_t::part *def)
{
if (arc.canSkip() && def != nullptr && !memcmp(&part, def, sizeof(part)))
{
return arc;
}
if (arc.BeginObject(key))
{
arc("xoffset", part.xOffset, def->xOffset)
("yoffset", part.yOffset, def->yOffset)
("xscale", part.xScale, def->xScale)
("yscale", part.yScale, def->yScale)
("texture", part.texture, def->texture)
("interpolation", part.interpolation)
.EndObject();
}
return arc;
}
//==========================================================================
//
//
//
//==========================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, side_t &side, side_t *def)
{
if (arc.BeginObject(key))
{
arc.Array("textures", side.textures, def->textures, 3, true)
("light", side.Light, def->Light)
("flags", side.Flags, def->Flags)
//("leftside", side.LeftSide)
//("rightside", side.RightSide)
//("index", side.Index)
("attacheddecals", side.AttachedDecals)
.EndObject();
}
return arc;
}
//==========================================================================
//
//
//
//==========================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, FLinkedSector &ls, FLinkedSector *def)
{
if (arc.BeginObject(key))
{
arc("sector", ls.Sector)
("type", ls.Type)
.EndObject();
}
return arc;
}
//==========================================================================
//
//
//
//==========================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, sector_t::splane &p, sector_t::splane *def)
{
if (arc.canSkip() && def != nullptr && !memcmp(&p, def, sizeof(p)))
{
return arc;
}
if (arc.BeginObject(key))
{
arc("xoffs", p.xform.xOffs, def->xform.xOffs)
("yoffs", p.xform.yOffs, def->xform.yOffs)
("xscale", p.xform.xScale, def->xform.xScale)
("yscale", p.xform.yScale, def->xform.yScale)
("angle", p.xform.Angle, def->xform.Angle)
("baseyoffs", p.xform.baseyOffs, def->xform.baseyOffs)
("baseangle", p.xform.baseAngle, def->xform.baseAngle)
("flags", p.Flags, def->Flags)
("light", p.Light, def->Light)
("texture", p.Texture, def->Texture)
("texz", p.TexZ, def->TexZ)
("alpha", p.alpha, def->alpha)
.EndObject();
}
return arc;
}
//==========================================================================
//
//
//
//==========================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, secplane_t &p, secplane_t *def)
{
if (arc.canSkip() && def != nullptr && !memcmp(&p, def, sizeof(p)))
{
return arc;
}
if (arc.BeginObject(key))
{
arc("normal", p.normal, def->normal)
("d", p.D, def->D)
.EndObject();
if (arc.isReading() && p.normal.Z != 0)
{
p.negiC = 1 / p.normal.Z;
}
}
return arc;
}
//==========================================================================
//
//
//
//==========================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t *def)
{
if (arc.BeginObject(key))
{
arc("floorplane", p.floorplane, def->floorplane)
("ceilingplane", p.ceilingplane, def->ceilingplane)
("lightlevel", p.lightlevel, def->lightlevel)
("special", p.special, def->special)
("soundtraversed", p.soundtraversed, def->soundtraversed)
("seqtype", p.seqType, def->seqType)
("seqname", p.SeqName, def->SeqName)
("friction", p.friction, def->friction)
("movefactor", p.movefactor, def->movefactor)
("stairlock", p.stairlock, def->stairlock)
("prevsec", p.prevsec, def->prevsec)
("nextsec", p.nextsec, def->nextsec)
.Array("planes", p.planes, def->planes, 2, true)
//("heightsec", p.heightsec)
//("bottommap", p.bottommap)
//("midmap", p.midmap)
//("topmap", p.topmap)
("damageamount", p.damageamount, def->damageamount)
("damageinterval", p.damageinterval, def->damageinterval)
("leakydamage", p.leakydamage, def->leakydamage)
("damagetype", p.damagetype, def->damagetype)
("sky", p.sky, def->sky)
("moreflags", p.MoreFlags, def->MoreFlags)
("flags", p.Flags, def->Flags)
.Array("portals", p.Portals, def->Portals, 2, true)
("zonenumber", p.ZoneNumber, def->ZoneNumber)
.Array("interpolations", p.interpolations, 4, true)
("soundtarget", p.SoundTarget)
("secacttarget", p.SecActTarget)
("floordata", p.floordata)
("ceilingdata", p.ceilingdata)
("lightingdata", p.lightingdata)
("fakefloor_sectors", p.e->FakeFloor.Sectors)
("midtexf_lines", p.e->Midtex.Floor.AttachedLines)
("midtexf_sectors", p.e->Midtex.Floor.AttachedSectors)
("midtexc_lines", p.e->Midtex.Ceiling.AttachedLines)
("midtexc_sectors", p.e->Midtex.Ceiling.AttachedSectors)
("linked_floor", p.e->Linked.Floor.Sectors)
("linked_ceiling", p.e->Linked.Ceiling.Sectors)
("colormap", p.ColorMap, def->ColorMap)
.Terrain("floorterrain", p.terrainnum[0], &def->terrainnum[0])
.Terrain("ceilingterrain", p.terrainnum[1], &def->terrainnum[1])
.EndObject();
}
return arc;
}
FSerializer &Serialize(FSerializer &arc, const char *key, subsector_t *&ss, subsector_t **)
{
BYTE by;
const char *str;
if (arc.isWriting())
{
if (hasglnodes)
{
TArray<char> encoded(1 + (numsubsectors + 5) / 6);
int p = 0;
for (int i = 0; i < numsubsectors; i += 6)
{
by = 0;
for (int j = 0; j < 6; j++)
{
if (i + j < numsubsectors && (subsectors[i + j].flags & SSECF_DRAWN))
{
by |= (1 << j);
}
}
if (by < 10) by += '0';
else if (by < 36) by += 'A' - 10;
else if (by < 62) by += 'a' - 36;
else if (by == 62) by = '-';
else if (by == 63) by = '+';
encoded[p++] = by;
}
encoded[p] = 0;
str = &encoded[0];
if (arc.BeginArray(key))
{
arc(nullptr, numvertexes)
(nullptr, numsubsectors)
.StringPtr(nullptr, str)
.EndArray();
}
}
}
else
{
int num_verts, num_subs;
if (arc.BeginArray(key))
{
arc(nullptr, num_verts)
(nullptr, num_subs)
.StringPtr(nullptr, str)
.EndArray();
}
}
return arc;
}
FSerializer &Serialize(FSerializer &arc, const char *key, ReverbContainer *&c, ReverbContainer **def)
{
int id = (arc.isReading() || c == nullptr) ? 0 : c->ID;
Serialize(arc, key, id, nullptr);
if (arc.isReading())
{
c = S_FindEnvironment(id);
}
return arc;
}
FSerializer &Serialize(FSerializer &arc, const char *key, zone_t &z, zone_t *def)
{
return Serialize(arc, key, z.Environment, nullptr);
}
//============================================================================
//
// Save a line portal for savegames.
//
//============================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, FLinePortal &port, FLinePortal *def)
{
if (arc.BeginObject(key))
{
arc("origin", port.mOrigin)
("destination", port.mDestination)
("displacement", port.mDisplacement)
("type", port.mType)
("flags", port.mFlags)
("defflags", port.mDefFlags)
("align", port.mAlign)
.EndObject();
}
return arc;
}
//============================================================================
//
// Save a sector portal for savegames.
//
//============================================================================
FSerializer &Serialize(FSerializer &arc, const char *key, FSectorPortal &port, FSectorPortal *def)
{
if (arc.BeginObject(key))
{
arc("type", port.mType)
("flags", port.mFlags)
("partner", port.mPartner)
("plane", port.mPlane)
("origin", port.mOrigin)
("destination", port.mDestination)
("displacement", port.mDisplacement)
("planez", port.mPlaneZ)
("skybox", port.mSkybox)
.EndObject();
}
return arc;
}
void DThinker::SaveList(FSerializer &arc, DThinker *node)
{
if (node != NULL)
{
while (!(node->ObjectFlags & OF_Sentinel))
{
assert(node->NextThinker != NULL && !(node->NextThinker->ObjectFlags & OF_EuthanizeMe));
::Serialize<DThinker>(arc, nullptr, node, nullptr);
node = node->NextThinker;
}
}
}
void DThinker::SerializeThinkers(FSerializer &arc, bool hubLoad)
{
//DThinker *thinker;
//BYTE stat;
//int statcount;
int i;
if (arc.isWriting())
{
arc.BeginArray("thinkers");
for (i = 0; i <= MAX_STATNUM; i++)
{
arc.BeginArray(nullptr);
SaveList(arc, Thinkers[i].GetHead());
SaveList(arc, FreshThinkers[i].GetHead());
arc.EndArray();
}
arc.EndArray();
}
else
{
}
}
void SerializeWorld(FSerializer &arc)
{
arc.Array("linedefs", lines, &loadlines[0], numlines)
.Array("sidedefs", sides, &loadsides[0], numsides)
.Array("sectors", sectors, &loadsectors[0], numsectors)
("subsectors", subsectors)
("zones", Zones)
("lineportals", linePortals)
("sectorportals", sectorPortals);
}
void DObject::SerializeUserVars(FSerializer &arc)
{
PSymbolTable *symt;
FName varname;
//DWORD count, j;
int *varloc = NULL;
symt = &GetClass()->Symbols;
if (arc.isWriting())
{
// Write all fields that aren't serialized by native code.
//GetClass()->WriteValue(arc, this);
}
else
{
//GetClass()->ReadValue(arc, this);
}
}
void DObject::Serialize(FSerializer &arc)
{
ObjectFlags |= OF_SerialSuccess;
}
//==========================================================================
//
// AActor :: Serialize
//
//==========================================================================
#define A(a,b) ((a), (b), def->b)
void AActor::Serialize(FSerializer &arc)
{
int damage = 0; // just a placeholder until the insanity surrounding the damage property can be fixed
AActor *def = GetDefault();
Super::Serialize(arc);
arc
.Sprite("sprite", sprite, &def->sprite)
A("pos", __Pos)
A("angles", Angles)
A("frame", frame)
A("scale", Scale)
A("renderstyle", RenderStyle)
A("renderflags", renderflags)
A("picnum", picnum)
A("floorpic", floorpic)
A("ceilingpic", ceilingpic)
A("tidtohate", TIDtoHate)
A("lastlookpn", LastLookPlayerNumber)
("lastlookactor", LastLookActor)
A("effects", effects)
A("alpha", Alpha)
A("fillcolor", fillcolor)
A("sector", Sector)
A("floorz", floorz)
A("ceilingz", ceilingz)
A("dropoffz", dropoffz)
A("floorsector", floorsector)
A("ceilingsector", ceilingsector)
A("radius", radius)
A("height", Height)
A("ppassheight", projectilepassheight)
A("vel", Vel)
A("tics", tics)
A("state", state)
("damage", damage)
.Terrain("floorterrain", floorterrain, &def->floorterrain)
A("projectilekickback", projectileKickback)
A("flags", flags)
A("flags2", flags2)
A("flags3", flags3)
A("flags4", flags4)
A("flags5", flags5)
A("flags6", flags6)
A("flags7", flags7)
A("weaponspecial", weaponspecial)
A("special1", special1)
A("special2", special2)
A("specialf1", specialf1)
A("specialf2", specialf2)
A("health", health)
A("movedir", movedir)
A("visdir", visdir)
A("movecount", movecount)
A("strafecount", strafecount)
("target", target)
("lastenemy", lastenemy)
("lastheard", LastHeard)
A("reactiontime", reactiontime)
A("threshold", threshold)
A("player", player)
A("spawnpoint", SpawnPoint)
A("spawnangle", SpawnAngle)
A("starthealth", StartHealth)
A("skillrespawncount", skillrespawncount)
("tracer", tracer)
A("floorclip", Floorclip)
A("tid", tid)
A("special", special)
.Args("args", args, def->args, special)
A("accuracy", accuracy)
A("stamina", stamina)
("goal", goal)
A("waterlevel", waterlevel)
A("minmissilechance", MinMissileChance)
A("spawnflags", SpawnFlags)
("inventory", Inventory)
A("inventoryid", InventoryID)
A("floatbobphase", FloatBobPhase)
A("translation", Translation)
A("seesound", SeeSound)
A("attacksound", AttackSound)
A("paimsound", PainSound)
A("deathsound", DeathSound)
A("activesound", ActiveSound)
A("usesound", UseSound)
A("bouncesound", BounceSound)
A("wallbouncesound", WallBounceSound)
A("crushpainsound", CrushPainSound)
A("speed", Speed)
A("floatspeed", FloatSpeed)
A("mass", Mass)
A("painchance", PainChance)
A("spawnstate", SpawnState)
A("seestate", SeeState)
A("meleestate", MeleeState)
A("missilestate", MissileState)
A("maxdropoffheight", MaxDropOffHeight)
A("maxstepheight", MaxStepHeight)
A("bounceflags", BounceFlags)
A("bouncefactor", bouncefactor)
A("wallbouncefactor", wallbouncefactor)
A("bouncecount", bouncecount)
A("maxtargetrange", maxtargetrange)
A("meleethreshold", meleethreshold)
A("meleerange", meleerange)
A("damagetype", DamageType)
A("damagetypereceived", DamageTypeReceived)
A("paintype", PainType)
A("deathtype", DeathType)
A("gravity", Gravity)
A("fastchasestrafecount", FastChaseStrafeCount)
("master", master)
A("smokecounter", smokecounter)
("blockingmobj", BlockingMobj)
A("blockingline", BlockingLine)
A("visibletoteam", VisibleToTeam)
A("pushfactor", pushfactor)
A("species", Species)
A("score", Score)
A("designatedteam", DesignatedTeam)
A("lastpush", lastpush)
A("lastbump", lastbump)
A("painthreshold", PainThreshold)
A("damagefactor", DamageFactor)
A("damagemultiply", DamageMultiply)
A("waveindexxy", WeaveIndexXY)
A("weaveindexz", WeaveIndexZ)
A("pdmgreceived", PoisonDamageReceived)
A("pdurreceived", PoisonDurationReceived)
A("ppreceived", PoisonPeriodReceived)
("poisoner", Poisoner)
A("posiondamage", PoisonDamage)
A("poisonduration", PoisonDuration)
A("poisonperiod", PoisonPeriod)
A("poisondamagetype", PoisonDamageType)
A("poisondmgtypereceived", PoisonDamageTypeReceived)
A("conversationroot", ConversationRoot)
A("conversation", Conversation)
A("friendplayer", FriendPlayer)
A("telefogsourcetype", TeleFogSourceType)
A("telefogdesttype", TeleFogDestType)
A("ripperlevel", RipperLevel)
A("riplevelmin", RipLevelMin)
A("riplevelmax", RipLevelMax)
A("devthreshold", DefThreshold)
A("spriteangle", SpriteAngle)
A("spriterotation", SpriteRotation)
("alternative", alternative)
A("tag", Tag);
}
CCMD(writejson)
{
DWORD t = I_MSTime();
FSerializer arc;
arc.OpenWriter();
arc.BeginObject(nullptr);
DThinker::SerializeThinkers(arc, false);
SerializeWorld(arc);
arc.WriteObjects();
arc.EndObject();
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);
*/
}