- implemented proper delta serialization for sectors and walls.

This commit is contained in:
Christoph Oelckers 2020-10-11 20:57:20 +02:00
parent f12c6b0319
commit b4a011300a
7 changed files with 137 additions and 88 deletions

View file

@ -129,10 +129,7 @@ void StartLevel(MapRecord* level)
memset(xsprite, 0, sizeof(xsprite)); memset(xsprite, 0, sizeof(xsprite));
memset(sprite, 0, kMaxSprites * sizeof(spritetype)); memset(sprite, 0, kMaxSprites * sizeof(spritetype));
//drawLoadingScreen(); //drawLoadingScreen();
if (dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsectnum, nullptr)) dbLoadMap(currentLevel->fileName, (int*)&startpos.x, (int*)&startpos.y, (int*)&startpos.z, &startang, &startsectnum, nullptr);
{
I_Error("%s: Unable to load map", level->DisplayName());
}
SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name); SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name);
STAT_NewLevel(currentLevel->fileName); STAT_NewLevel(currentLevel->fileName);
wsrand(dbReadMapCRC(currentLevel->LabelName())); wsrand(dbReadMapCRC(currentLevel->LabelName()));

View file

@ -457,10 +457,41 @@ struct spritetypedisk
int16_t hitag; int16_t hitag;
int16_t extra; int16_t extra;
}; };
struct sectortypedisk
{
int16_t wallptr, wallnum;
int32_t ceilingz, floorz;
uint16_t ceilingstat, floorstat;
int16_t ceilingpicnum, ceilingheinum;
int8_t ceilingshade;
uint8_t ceilingpal, ceilingxpanning, ceilingypanning;
int16_t floorpicnum, floorheinum;
int8_t floorshade;
uint8_t floorpal, floorxpanning, floorypanning;
uint8_t visibility, fogpal;
int16_t type;
int16_t hitag;
int16_t extra;
};
struct walltypedisk
{
int32_t x, y;
int16_t point2, nextwall, nextsector;
uint16_t cstat;
int16_t picnum, overpicnum;
int8_t shade;
uint8_t pal, xrepeat, yrepeat, xpanning, ypanning;
int16_t type;
int16_t hitag;
int16_t extra;
};
#pragma pack(pop) #pragma pack(pop)
int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short *pSector, unsigned int *pCRC) { void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short *pSector, unsigned int *pCRC) {
int16_t tpskyoff[256]; int16_t tpskyoff[256];
ClearAutomap(); ClearAutomap();
#ifdef NOONE_EXTENSIONS #ifdef NOONE_EXTENSIONS
@ -477,15 +508,13 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
if (!fr.isOpen()) if (!fr.isOpen())
{ {
Printf("Error opening map file %s", mapname.GetChars()); I_Error("Error opening map file %s", mapname.GetChars());
return -1;
} }
MAPSIGNATURE header; MAPSIGNATURE header;
fr.Read(&header, 6); fr.Read(&header, 6);
if (memcmp(header.signature, "BLM\x1a", 4)) if (memcmp(header.signature, "BLM\x1a", 4))
{ {
Printf("%s: Map file corrupted", mapname.GetChars()); I_Error("%s: Map file corrupted", mapname.GetChars());
return -1;
} }
byte_1A76C8 = 0; byte_1A76C8 = 0;
if ((LittleShort(header.version) & 0xff00) == 0x700) { if ((LittleShort(header.version) & 0xff00) == 0x700) {
@ -499,8 +528,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
#endif #endif
} else { } else {
Printf("%s: Map file is wrong version", mapname.GetChars()); I_Error("%s: Map file is wrong version", mapname.GetChars());
return -1;
} }
MAPHEADER mapHeader; MAPHEADER mapHeader;
@ -542,14 +570,12 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
} }
else else
{ {
Printf("%s: Corrupted Map file", mapname.GetChars()); I_Error("%s: Corrupted Map file", mapname.GetChars());
return -1;
} }
} }
else if (mapHeader.at16) else if (mapHeader.at16)
{ {
Printf("%s: Corrupted Map file", mapname.GetChars()); I_Error("%s: Corrupted Map file", mapname.GetChars());
return -1;
} }
parallaxtype = mapHeader.at1a; parallaxtype = mapHeader.at1a;
gMapRev = mapHeader.at1b; gMapRev = mapHeader.at1b;
@ -587,27 +613,37 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
for (int i = 0; i < numsectors; i++) for (int i = 0; i < numsectors; i++)
{ {
sectortype *pSector = &sector[i]; sectortype *pSector = &sector[i];
fr.Read(pSector, sizeof(sectortype)); sectortypedisk load;
fr.Read(&load, sizeof(sectortypedisk));
if (byte_1A76C8) if (byte_1A76C8)
{ {
dbCrypt((char*)pSector, sizeof(sectortype), gMapRev*sizeof(sectortype)); dbCrypt((char*)&load, sizeof(sectortypedisk), gMapRev*sizeof(sectortypedisk));
} }
pSector->wallptr = LittleShort(pSector->wallptr); pSector->wallptr = LittleShort(load.wallptr);
pSector->wallnum = LittleShort(pSector->wallnum); pSector->wallnum = LittleShort(load.wallnum);
pSector->ceilingz = LittleLong(pSector->ceilingz); pSector->ceilingz = LittleLong(load.ceilingz);
pSector->floorz = LittleLong(pSector->floorz); pSector->floorz = LittleLong(load.floorz);
pSector->ceilingstat = LittleShort(pSector->ceilingstat); pSector->ceilingstat = LittleShort(load.ceilingstat);
pSector->floorstat = LittleShort(pSector->floorstat); pSector->floorstat = LittleShort(load.floorstat);
pSector->ceilingpicnum = LittleShort(pSector->ceilingpicnum); pSector->ceilingpicnum = LittleShort(load.ceilingpicnum);
pSector->ceilingheinum = LittleShort(pSector->ceilingheinum); pSector->ceilingheinum = LittleShort(load.ceilingheinum);
pSector->floorpicnum = LittleShort(pSector->floorpicnum); pSector->floorpicnum = LittleShort(load.floorpicnum);
pSector->floorheinum = LittleShort(pSector->floorheinum); pSector->floorheinum = LittleShort(load.floorheinum);
pSector->type = LittleShort(pSector->type); pSector->type = LittleShort(load.type);
pSector->hitag = LittleShort(pSector->hitag); pSector->hitag = LittleShort(load.hitag);
pSector->extra = LittleShort(pSector->extra); pSector->extra = LittleShort(load.extra);
pSector->ceilingshade = load.ceilingshade;
qsector_filler[i] = pSector->fogpal; pSector->ceilingpal = load.ceilingpal;
pSector->ceilingxpanning = load.ceilingxpanning;
pSector->ceilingypanning = load.ceilingypanning;
pSector->floorshade = load.floorshade;
pSector->floorpal = load.floorpal;
pSector->floorxpanning = load.floorxpanning;
pSector->floorypanning = load.floorypanning;
pSector->visibility = load.visibility;
qsector_filler[i] = load.fogpal;
pSector->fogpal = 0; pSector->fogpal = 0;
if (sector[i].extra > 0) if (sector[i].extra > 0)
{ {
char pBuffer[nXSectorSize]; char pBuffer[nXSectorSize];
@ -711,22 +747,30 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
for (int i = 0; i < numwalls; i++) for (int i = 0; i < numwalls; i++)
{ {
walltype *pWall = &wall[i]; walltype *pWall = &wall[i];
fr.Read(pWall, sizeof(walltype)); walltypedisk load;
fr.Read(&load, sizeof(walltypedisk));
if (byte_1A76C8) if (byte_1A76C8)
{ {
dbCrypt((char*)pWall, sizeof(walltype), (gMapRev*sizeof(sectortype)) | 0x7474614d); dbCrypt((char*)&load, sizeof(walltypedisk), (gMapRev*sizeof(sectortypedisk)) | 0x7474614d);
} }
pWall->x = LittleLong(pWall->x); pWall->x = LittleLong(load.x);
pWall->y = LittleLong(pWall->y); pWall->y = LittleLong(load.y);
pWall->point2 = LittleShort(pWall->point2); pWall->point2 = LittleShort(load.point2);
pWall->nextwall = LittleShort(pWall->nextwall); pWall->nextwall = LittleShort(load.nextwall);
pWall->nextsector = LittleShort(pWall->nextsector); pWall->nextsector = LittleShort(load.nextsector);
pWall->cstat = LittleShort(pWall->cstat); pWall->cstat = LittleShort(load.cstat);
pWall->picnum = LittleShort(pWall->picnum); pWall->picnum = LittleShort(load.picnum);
pWall->overpicnum = LittleShort(pWall->overpicnum); pWall->overpicnum = LittleShort(load.overpicnum);
pWall->type = LittleShort(pWall->type); pWall->type = LittleShort(load.type);
pWall->hitag = LittleShort(pWall->hitag); pWall->hitag = LittleShort(load.hitag);
pWall->extra = LittleShort(pWall->extra); pWall->extra = LittleShort(load.extra);
pWall->shade = load.shade;
pWall->pal = load.pal;
pWall->xrepeat = load.xrepeat;
pWall->xpanning = load.xpanning;
pWall->yrepeat = load.yrepeat;
pWall->ypanning = load.ypanning;
if (wall[i].extra > 0) if (wall[i].extra > 0)
{ {
char pBuffer[nXWallSize]; char pBuffer[nXWallSize];
@ -927,8 +971,7 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
if (CalcCRC32(buffer.Data(), buffer.Size() -4) != nCRC) if (CalcCRC32(buffer.Data(), buffer.Size() -4) != nCRC)
{ {
Printf("%s: Map File does not match CRC", mapname.GetChars()); I_Error("%s: Map File does not match CRC", mapname.GetChars());
return -1;
} }
if (pCRC) if (pCRC)
*pCRC = nCRC; *pCRC = nCRC;
@ -945,14 +988,12 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
} }
else else
{ {
Printf("%s: Corrupted Map file", mapname.GetChars()); I_Error("%s: Corrupted Map file", mapname.GetChars());
return -1;
} }
} }
else if (gSongId != 0) else if (gSongId != 0)
{ {
Printf("%s: Corrupted Map file", mapname.GetChars()); I_Error("%s: Corrupted Map file", mapname.GetChars());
return -1;
} }
if ((header.version & 0xff00) == 0x600) if ((header.version & 0xff00) == 0x600)
@ -1002,14 +1043,18 @@ int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short
} }
} }
return 0;
}
int32_t qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang, int16_t* dacursectnum) memcpy(wallbackup, wall, sizeof(wallbackup));
{ memcpy(sectorbackup, sector, sizeof(sectorbackup));
// NUKE-TODO: implement flags, see mapedit.cpp // todo: back up xsector and xwall as well
return dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, (short*)daang, (short*)dacursectnum, NULL);
} }
END_BLD_NS END_BLD_NS
// only used by the backup loader.
void qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang, int16_t* dacursectnum)
{
Blood::dbLoadMap(filename, &dapos->x, &dapos->y, &dapos->z, (short*)daang, (short*)dacursectnum, NULL);
Blood::dbInit(); // clean up immediately.
}

View file

@ -356,6 +356,6 @@ unsigned short dbInsertXSector(int nSector);
void dbInit(void); void dbInit(void);
void PropagateMarkerReferences(void); void PropagateMarkerReferences(void);
unsigned int dbReadMapCRC(const char *pPath); unsigned int dbReadMapCRC(const char *pPath);
int dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short *pSector, unsigned int *pCRC); void dbLoadMap(const char *pPath, int *pX, int *pY, int *pZ, short *pAngle, short *pSector, unsigned int *pCRC);
END_BLD_NS END_BLD_NS

View file

@ -76,7 +76,6 @@ int32_t qinsertsprite(int16_t nSector, int16_t nStat);
int32_t qdeletesprite(int16_t nSprite); int32_t qdeletesprite(int16_t nSprite);
int32_t qchangespritesect(int16_t nSprite, int16_t nSector); int32_t qchangespritesect(int16_t nSprite, int16_t nSector);
int32_t qchangespritestat(int16_t nSprite, int16_t nStatus); int32_t qchangespritestat(int16_t nSprite, int16_t nStatus);
int32_t qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang, int16_t* dacursectnum);
void HookReplaceFunctions(void) void HookReplaceFunctions(void)
{ {

View file

@ -248,7 +248,6 @@ struct usermaphack_t
extern usermaphack_t g_loadedMapHack; extern usermaphack_t g_loadedMapHack;
#if !defined DEBUG_MAIN_ARRAYS
EXTERN spriteext_t *spriteext; EXTERN spriteext_t *spriteext;
EXTERN spritesmooth_t *spritesmooth; EXTERN spritesmooth_t *spritesmooth;
@ -256,31 +255,16 @@ EXTERN sectortype *sector;
EXTERN walltype *wall; EXTERN walltype *wall;
EXTERN spritetype *sprite; EXTERN spritetype *sprite;
EXTERN tspriteptr_t tsprite; EXTERN tspriteptr_t tsprite;
#else
#endif extern sectortype sectorbackup[MAXSECTORS];
extern walltype wallbackup[MAXWALLS];
static inline tspriteptr_t renderMakeTSpriteFromSprite(tspriteptr_t const tspr, uint16_t const spritenum) static inline tspriteptr_t renderMakeTSpriteFromSprite(tspriteptr_t const tspr, uint16_t const spritenum)
{ {
auto const spr = &sprite[spritenum]; auto const spr = &sprite[spritenum];
tspr->pos = spr->pos; *tspr = *spr;
tspr->cstat = spr->cstat;
tspr->picnum = spr->picnum;
tspr->shade = spr->shade;
tspr->pal = spr->pal;
tspr->blend = spr->blend;
tspr->xrepeat = spr->xrepeat;
tspr->yrepeat = spr->yrepeat;
tspr->xoffset = spr->xoffset;
tspr->yoffset = spr->yoffset;
tspr->sectnum = spr->sectnum;
tspr->statnum = spr->statnum;
tspr->ang = spr->ang;
tspr->vel = spr->vel;
tspr->lotag = spr->lotag;
tspr->hitag = spr->hitag;
tspr->extra = spr->extra;
tspr->clipdist = 0; tspr->clipdist = 0;
tspr->owner = spritenum; tspr->owner = spritenum;
@ -561,9 +545,8 @@ void engineUnInit(void);
void initspritelists(void); void initspritelists(void);
void engineLoadBoard(const char *filename, int flags, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum); void engineLoadBoard(const char *filename, int flags, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum);
int32_t engineLoadMHK(const char *filename); void loadMapBackup(const char* filename);
void G_LoadMapHack(const char* filename); void G_LoadMapHack(const char* filename);
int32_t saveboard(const char *filename, const vec3_t *dapos, int16_t daang, int16_t dacursectnum);
int32_t qloadkvx(int32_t voxindex, const char *filename); int32_t qloadkvx(int32_t voxindex, const char *filename);
void vox_undefine(int32_t const); void vox_undefine(int32_t const);

View file

@ -40,6 +40,7 @@
#include "printf.h" #include "printf.h"
#include "inputstate.h" #include "inputstate.h"
#include "md4.h" #include "md4.h"
#include "gamecontrol.h"
static void ReadSectorV7(FileReader& fr, sectortype& sect) static void ReadSectorV7(FileReader& fr, sectortype& sect)
@ -63,7 +64,7 @@ static void ReadSectorV7(FileReader& fr, sectortype& sect)
sect.floorxpanning = fr.ReadUInt8(); sect.floorxpanning = fr.ReadUInt8();
sect.floorypanning = fr.ReadUInt8(); sect.floorypanning = fr.ReadUInt8();
sect.visibility = fr.ReadUInt8(); sect.visibility = fr.ReadUInt8();
sect.fogpal = fr.ReadUInt8(); // note: currently unused. sect.fogpal = fr.ReadUInt8(); // note: currently unused, except for Blood.
sect.lotag = fr.ReadInt16(); sect.lotag = fr.ReadInt16();
sect.hitag = fr.ReadInt16(); sect.hitag = fr.ReadInt16();
sect.extra = fr.ReadInt16(); sect.extra = fr.ReadInt16();
@ -440,4 +441,27 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang,
guniqhudid = 0; guniqhudid = 0;
G_LoadMapHack(filename); G_LoadMapHack(filename);
memcpy(wallbackup, wall, sizeof(wallbackup));
memcpy(sectorbackup, sector, sizeof(sectorbackup));
}
void qloadboard(const char* filename, char flags, vec3_t* dapos, int16_t* daang, int16_t* dacursectnum);
// loads a map into the backup buffer.
void loadMapBackup(const char* filename)
{
vec3_t pos;
int16_t scratch;
if (g_gameType & GAMEFLAG_BLOOD)
{
qloadboard(filename, 0, &pos, &scratch, &scratch);
}
else
{
engineLoadBoard(filename, 0, &pos, &scratch, &scratch);
initspritelists();
}
} }

View file

@ -56,6 +56,10 @@
#include "gamestate.h" #include "gamestate.h"
#include "razemenu.h" #include "razemenu.h"
sectortype sectorbackup[MAXSECTORS];
walltype wallbackup[MAXWALLS];
static CompositeSavegameWriter savewriter; static CompositeSavegameWriter savewriter;
static FResourceFile *savereader; static FResourceFile *savereader;
void LoadEngineState(); void LoadEngineState();
@ -135,6 +139,7 @@ bool OpenSaveGameForRead(const char *name)
info->Unlock(); info->Unlock();
// Load system-side data from savegames. // Load system-side data from savegames.
loadMapBackup(currentLevel->fileName);
LoadEngineState(); LoadEngineState();
SerializeSession(arc); // must be AFTER LoadEngineState because it needs info from it. SerializeSession(arc); // must be AFTER LoadEngineState because it needs info from it.
gi->SerializeGameState(arc); gi->SerializeGameState(arc);
@ -468,8 +473,6 @@ static walltype zwal;
FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectortype *def) FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectortype *def)
{ {
def = &zsec;
if (arc.isReading()) c = {};
if (arc.BeginObject(key)) if (arc.BeginObject(key))
{ {
arc("wallptr", c.wallptr, def->wallptr) arc("wallptr", c.wallptr, def->wallptr)
@ -502,8 +505,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectort
FSerializer &Serialize(FSerializer &arc, const char *key, walltype &c, walltype *def) FSerializer &Serialize(FSerializer &arc, const char *key, walltype &c, walltype *def)
{ {
def = &zwal;
if (arc.isReading()) c = {};
if (arc.BeginObject(key)) if (arc.BeginObject(key))
{ {
arc("x", c.x, def->x) arc("x", c.x, def->x)
@ -533,9 +534,9 @@ void SerializeMap(FSerializer& arc)
if (arc.BeginObject("engine")) if (arc.BeginObject("engine"))
{ {
arc ("numsectors", numsectors) arc ("numsectors", numsectors)
.Array("sectors", sector, numsectors) .Array("sectors", sector, sectorbackup, numsectors)
("numwalls", numwalls) ("numwalls", numwalls)
.Array("walls", wall, numwalls) .Array("walls", wall, wallbackup, numwalls)
.EndObject(); .EndObject();
} }