mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-27 20:20:40 +00:00
- save the entire engine state as JSON.
The sprite lists may still need optimization. Due to different handling between Blood and the core engine they need to be written out completely which is quite wasteful.
This commit is contained in:
parent
bdc1f66131
commit
817fa8aba3
10 changed files with 180 additions and 181 deletions
|
@ -82,7 +82,6 @@ kMediumGoo = 2,
|
|||
|
||||
// STATNUMS /////////////////////////////////////////////////////
|
||||
enum {
|
||||
kStatNothing = -1,
|
||||
kStatDecoration = 0,
|
||||
kStatFX = 1,
|
||||
kStatExplosion = 2,
|
||||
|
|
|
@ -104,7 +104,7 @@ void RemoveSpriteSect(int nSprite)
|
|||
{
|
||||
headspritesect[nSector] = nextspritesect[nSprite];
|
||||
}
|
||||
sprite[nSprite].sectnum = -1;
|
||||
sprite[nSprite].sectnum = MAXSECTORS;
|
||||
}
|
||||
|
||||
void InsertSpriteStat(int nSprite, int nStat)
|
||||
|
@ -148,7 +148,7 @@ void RemoveSpriteStat(int nSprite)
|
|||
{
|
||||
headspritestat[nStat] = nextspritestat[nSprite];
|
||||
}
|
||||
sprite[nSprite].statnum = kStatNothing;
|
||||
sprite[nSprite].statnum = MAXSTATUS;
|
||||
gStatCount[nStat]--;
|
||||
}
|
||||
|
||||
|
|
|
@ -201,12 +201,7 @@ typedef struct {
|
|||
int16_t angoff, pitch, roll;
|
||||
vec3_t pivot_offset, position_offset;
|
||||
uint8_t flags;
|
||||
uint8_t xpanning, ypanning; // EDuke script hacks.
|
||||
uint8_t filler;
|
||||
uint32_t filler2;
|
||||
float alpha;
|
||||
// NOTE: keep 'tspr' on an 8-byte boundary:
|
||||
tspriteptr_t tspr;
|
||||
} spriteext_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -328,7 +323,6 @@ enum {
|
|||
PALETTE_TRANSLUC = 1<<2,
|
||||
};
|
||||
|
||||
EXTERN char showinvisibility;
|
||||
EXTERN int32_t g_visibility, parallaxvisibility;
|
||||
|
||||
// blendtable[1] to blendtable[numalphatabs] are considered to be
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "m_alloc.h"
|
||||
#include "intvec.h"
|
||||
#include "m_swap.h"
|
||||
#include "serializer.h"
|
||||
|
||||
////////// Compiler detection //////////
|
||||
|
||||
|
@ -242,5 +243,18 @@ void bfirst_search_try(T *const list, uint8_t *const bitmap, T *const eltnumptr,
|
|||
|
||||
/* End dependence on compat.o object. */
|
||||
|
||||
inline FSerializer& Serialize(FSerializer& arc, const char* key, vec3_t& c, vec3_t* def)
|
||||
{
|
||||
if (def && !memcmp(&c, def, sizeof(c))) return arc;
|
||||
if (arc.BeginObject(key))
|
||||
{
|
||||
arc("x", c.x, def? &def->x : nullptr)
|
||||
("y", c.y, def ? &def->y : nullptr)
|
||||
("z", c.z, def ? &def->z : nullptr)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
|
||||
#endif // compat_h_
|
||||
|
|
|
@ -943,8 +943,6 @@ int32_t engineInit(void)
|
|||
|
||||
xyaspect = -1;
|
||||
|
||||
showinvisibility = 0;
|
||||
|
||||
voxelmemory.Reset();
|
||||
|
||||
for (i=0; i<MAXTILES; i++)
|
||||
|
|
|
@ -2231,7 +2231,7 @@ void polymost_scansector(int32_t sectnum)
|
|||
{
|
||||
auto const spr = (uspriteptr_t)&sprite[z];
|
||||
|
||||
if ((spr->cstat & 0x8000 && !showinvisibility) || spr->xrepeat == 0 || spr->yrepeat == 0)
|
||||
if ((spr->cstat & 0x8000) || spr->xrepeat == 0 || spr->yrepeat == 0)
|
||||
continue;
|
||||
|
||||
vec2_t const s = { spr->x-globalposx, spr->y-globalposy };
|
||||
|
@ -3204,21 +3204,6 @@ void polymost_drawsprite(int32_t snum)
|
|||
otex.v = -ytex.v * (pxy[3].y + .001f);
|
||||
}
|
||||
|
||||
// sprite panning
|
||||
if (spriteext[spritenum].xpanning)
|
||||
{
|
||||
ytex.u -= ytex.d * ((float) (spriteext[spritenum].xpanning) * (1.0f / 255.f)) * ftsiz.x;
|
||||
otex.u -= otex.d * ((float) (spriteext[spritenum].xpanning) * (1.0f / 255.f)) * ftsiz.x;
|
||||
drawpoly_srepeat = 1;
|
||||
}
|
||||
|
||||
if (spriteext[spritenum].ypanning)
|
||||
{
|
||||
ytex.v -= ytex.d * ((float) (spriteext[spritenum].ypanning) * (1.0f / 255.f)) * ftsiz.y;
|
||||
otex.v -= otex.d * ((float) (spriteext[spritenum].ypanning) * (1.0f / 255.f)) * ftsiz.y;
|
||||
drawpoly_trepeat = 1;
|
||||
}
|
||||
|
||||
// Clip sprites to ceilings/floors when no parallaxing and not sloped
|
||||
if (!(sector[tspr->sectnum].ceilingstat & 3))
|
||||
{
|
||||
|
@ -3363,15 +3348,6 @@ void polymost_drawsprite(int32_t snum)
|
|||
t1 = 1.f - t1;
|
||||
}
|
||||
|
||||
// sprite panning
|
||||
if (spriteext[spritenum].xpanning)
|
||||
{
|
||||
float const xpan = ((float)(spriteext[spritenum].xpanning) * (1.0f / 255.f));
|
||||
t0 -= xpan;
|
||||
t1 -= xpan;
|
||||
drawpoly_srepeat = 1;
|
||||
}
|
||||
|
||||
xtex.u = (t0 * ryp0 - t1 * ryp1) * gxyaspect * ftsiz.x / (sx0 - sx1);
|
||||
ytex.u = 0;
|
||||
otex.u = t0 * ryp0 * gxyaspect * ftsiz.x - xtex.u * sx0;
|
||||
|
@ -3401,16 +3377,6 @@ void polymost_drawsprite(int32_t snum)
|
|||
otex.v = -xtex.v * sx0 - ytex.v * sf0;
|
||||
}
|
||||
|
||||
// sprite panning
|
||||
if (spriteext[spritenum].ypanning)
|
||||
{
|
||||
float const ypan = ((float)(spriteext[spritenum].ypanning) * (1.0f / 255.f)) * ftsiz.y;
|
||||
xtex.v -= xtex.d * ypan;
|
||||
ytex.v -= ytex.d * ypan;
|
||||
otex.v -= otex.d * ypan;
|
||||
drawpoly_trepeat = 1;
|
||||
}
|
||||
|
||||
// Clip sprites to ceilings/floors when no parallaxing
|
||||
if (!(sector[tspr->sectnum].ceilingstat & 1))
|
||||
{
|
||||
|
@ -3596,23 +3562,6 @@ void polymost_drawsprite(int32_t snum)
|
|||
otex.u = ftsiz.x * otex.d - otex.u;
|
||||
}
|
||||
|
||||
// sprite panning
|
||||
if (spriteext[spritenum].xpanning)
|
||||
{
|
||||
float const f = ((float)(spriteext[spritenum].xpanning) * (1.0f / 255.f)) * ftsiz.x;
|
||||
ytex.u -= ytex.d * f;
|
||||
otex.u -= otex.d * f;
|
||||
drawpoly_srepeat = 1;
|
||||
}
|
||||
|
||||
if (spriteext[spritenum].ypanning)
|
||||
{
|
||||
float const f = ((float)(spriteext[spritenum].ypanning) * (1.0f / 255.f)) * ftsiz.y;
|
||||
ytex.v -= ytex.d * f;
|
||||
otex.v -= otex.d * f;
|
||||
drawpoly_trepeat = 1;
|
||||
}
|
||||
|
||||
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
|
||||
pow2xsplit = 0;
|
||||
|
||||
|
|
|
@ -125,6 +125,12 @@ public:
|
|||
return Serialize(*this, key, obj, save_full? nullptr : &def);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
FSerializer& operator()(const char* key, T& obj, T* def)
|
||||
{
|
||||
return Serialize(*this, key, obj, !def || save_full ? nullptr : def);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
FSerializer &Array(const char *key, T *obj, int count, bool fullcompare = false)
|
||||
{
|
||||
|
@ -172,6 +178,29 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
template<class T, class Map>
|
||||
FSerializer &SparseArray(const char *key, T *obj, int count, const Map &map, bool fullcompare = false)
|
||||
{
|
||||
if (BeginArray(key))
|
||||
{
|
||||
int max = count;
|
||||
if (isReading())
|
||||
{
|
||||
max = ArraySize();
|
||||
}
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (map[i])
|
||||
{
|
||||
Serialize(*this, nullptr, obj[i], (T*)nullptr);
|
||||
if (--max < 0) break;
|
||||
}
|
||||
}
|
||||
EndArray();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
FSerializer &Enum(const char *key, T &obj)
|
||||
{
|
||||
|
|
|
@ -62,11 +62,10 @@ walltype wallbackup[MAXWALLS];
|
|||
|
||||
static CompositeSavegameWriter savewriter;
|
||||
static FResourceFile *savereader;
|
||||
void LoadEngineState();
|
||||
void SaveEngineState();
|
||||
void WriteSavePic(FileWriter* file, int width, int height);
|
||||
extern FString BackupSaveGame;
|
||||
void SerializeMap(FSerializer &arc);
|
||||
FixedBitArray<MAXSPRITES> activeSprites;
|
||||
|
||||
CVAR(String, cl_savedir, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
|
@ -140,8 +139,7 @@ bool OpenSaveGameForRead(const char *name)
|
|||
|
||||
// Load system-side data from savegames.
|
||||
loadMapBackup(currentLevel->fileName);
|
||||
LoadEngineState();
|
||||
SerializeSession(arc); // must be AFTER LoadEngineState because it needs info from it.
|
||||
SerializeSession(arc);
|
||||
gi->SerializeGameState(arc);
|
||||
}
|
||||
return savereader != nullptr;
|
||||
|
@ -236,7 +234,6 @@ bool OpenSaveGameForWrite(const char* filename, const char *name)
|
|||
// Handle system-side modules that need to persist data in savegames here, in a central place.
|
||||
savegamesession.OpenWriter(save_formatted);
|
||||
SerializeSession(savegamesession);
|
||||
SaveEngineState();
|
||||
gi->SerializeGameState(savegamesession);
|
||||
buff = savegamesession.GetCompressedOutput();
|
||||
AddCompressedSavegameChunk("session.json", buff);
|
||||
|
@ -431,24 +428,6 @@ FString G_BuildSaveName (const char *prefix)
|
|||
#include "build.h"
|
||||
#include "mmulti.h"
|
||||
|
||||
static void sv_prespriteextsave()
|
||||
{
|
||||
for (int i = 0; i < MAXSPRITES; i++)
|
||||
if (spriteext[i].mdanimtims)
|
||||
{
|
||||
spriteext[i].mdanimtims -= mdtims;
|
||||
if (spriteext[i].mdanimtims == 0)
|
||||
spriteext[i].mdanimtims++;
|
||||
}
|
||||
}
|
||||
static void sv_postspriteext()
|
||||
{
|
||||
for (int i = 0; i < MAXSPRITES; i++)
|
||||
if (spriteext[i].mdanimtims)
|
||||
spriteext[i].mdanimtims += mdtims;
|
||||
}
|
||||
|
||||
|
||||
static const int magic = 0xbeefcafe;
|
||||
void WriteMagic(FileWriter *fw)
|
||||
{
|
||||
|
@ -468,8 +447,68 @@ void CheckMagic(FileReader& fr)
|
|||
|
||||
#define V(x) x
|
||||
static spritetype zsp;
|
||||
static sectortype zsec;
|
||||
static walltype zwal;
|
||||
static spriteext_t zspx;
|
||||
|
||||
FSerializer &Serialize(FSerializer &arc, const char *key, spritetype &c, spritetype *def)
|
||||
{
|
||||
def = &zsp; // always delta against 0
|
||||
if (arc.BeginObject(key))
|
||||
{
|
||||
arc("x", c.x, def->x)
|
||||
("y", c.y, def->y)
|
||||
("z", c.z, def->z)
|
||||
("cstat", c.cstat, def->cstat)
|
||||
("picnum", c.picnum, def->picnum)
|
||||
("shade", c.shade, def->shade)
|
||||
("pal", c.pal, def->pal)
|
||||
("clipdist", c.clipdist, def->clipdist)
|
||||
("blend", c.blend, def->blend)
|
||||
("xrepeat", c.xrepeat, def->xrepeat)
|
||||
("yrepeat", c.yrepeat, def->yrepeat)
|
||||
("xoffset", c.xoffset, def->xoffset)
|
||||
("yoffset", c.yoffset, def->yoffset)
|
||||
("statnum", c.statnum)
|
||||
("sectnum", c.sectnum)
|
||||
("ang", c.ang, def->ang)
|
||||
("owner", c.owner, def->owner)
|
||||
("xvel", c.xvel, def->xvel)
|
||||
("yvel", c.yvel, def->yvel)
|
||||
("zvel", c.zvel, def->zvel)
|
||||
("lotag", c.lotag, def->lotag)
|
||||
("hitag", c.hitag, def->hitag)
|
||||
("extra", c.extra, def->extra)
|
||||
("detail", c.detail, def->detail)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* key, spriteext_t& c, spriteext_t* def)
|
||||
{
|
||||
if (arc.isWriting() && c.mdanimtims)
|
||||
{
|
||||
c.mdanimtims -= mdtims;
|
||||
if (c.mdanimtims == 0) c.mdanimtims++;
|
||||
}
|
||||
|
||||
def = &zspx; // always delta against 0
|
||||
if (arc.BeginObject(key))
|
||||
{
|
||||
arc("mdanimtims", c.mdanimtims, def->mdanimtims)
|
||||
("mdanimcur", c.mdanimcur, def->mdanimcur)
|
||||
("angoff", c.angoff, def->angoff)
|
||||
("pitch", c.pitch, def->pitch)
|
||||
("roll", c.roll, def->roll)
|
||||
("pivot_offset", c.pivot_offset, def->pivot_offset)
|
||||
("position_offset", c.position_offset, def->position_offset)
|
||||
("flags", c.flags, def->flags)
|
||||
("alpha", c.alpha, def->alpha)
|
||||
.EndObject();
|
||||
}
|
||||
|
||||
if (c.mdanimtims) c.mdanimtims += mdtims;
|
||||
return arc;
|
||||
}
|
||||
|
||||
FSerializer &Serialize(FSerializer &arc, const char *key, sectortype &c, sectortype *def)
|
||||
{
|
||||
|
@ -529,109 +568,88 @@ FSerializer &Serialize(FSerializer &arc, const char *key, walltype &c, walltype
|
|||
return arc;
|
||||
}
|
||||
|
||||
|
||||
void SerializeMap(FSerializer& arc)
|
||||
{
|
||||
// create a map of all used sprites so that we can use that elsewhere to only save what's needed.
|
||||
activeSprites.Zero();
|
||||
if (arc.isWriting())
|
||||
{
|
||||
for (int i=0; i<MAXSPRITES;i++)
|
||||
{
|
||||
if (sprite[i].statnum != MAXSTATUS)
|
||||
{
|
||||
activeSprites.Set(i);
|
||||
}
|
||||
}
|
||||
// simplify the data a bit for better compression.
|
||||
for (int i = 0; i < MAXSPRITES; i++)
|
||||
{
|
||||
if (nextspritestat[i] == i + 1) nextspritestat[i] = -2;
|
||||
if (nextspritesect[i] == i + 1) nextspritesect[i] = -2;
|
||||
if (prevspritestat[i] == i - 1) prevspritestat[i] = -2;
|
||||
if (prevspritesect[i] == i - 1) prevspritesect[i] = -2;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(sprite, 0, sizeof(sprite[0]) * MAXSPRITES);
|
||||
initspritelists();
|
||||
zsp = sprite[0];
|
||||
}
|
||||
|
||||
if (arc.BeginObject("engine"))
|
||||
{
|
||||
arc ("numsectors", numsectors)
|
||||
arc.SerializeMemory("activesprites", activeSprites.Storage(), activeSprites.StorageSize())
|
||||
.SparseArray("sprites", sprite, MAXSPRITES, activeSprites)
|
||||
.SparseArray("spriteext", spriteext, MAXSPRITES, activeSprites)
|
||||
("numsectors", numsectors)
|
||||
.Array("sectors", sector, sectorbackup, numsectors)
|
||||
("numwalls", numwalls)
|
||||
.Array("walls", wall, wallbackup, numwalls)
|
||||
.EndObject();
|
||||
}
|
||||
.Array("headspritestat", headspritestat, MAXSTATUS + 1)
|
||||
.Array("nextspritestat", nextspritestat, MAXSPRITES)
|
||||
.Array("prevspritestat", prevspritestat, MAXSPRITES)
|
||||
.Array("headspritesect", headspritesect, MAXSECTORS + 1)
|
||||
.Array("nextspritesect", nextspritesect, MAXSPRITES)
|
||||
.Array("prevspritesect", prevspritesect, MAXSPRITES)
|
||||
|
||||
("tailspritefree", tailspritefree)
|
||||
("myconnectindex", myconnectindex)
|
||||
("connecthead", connecthead)
|
||||
.Array("connectpoint2", connectpoint2, countof(connectpoint2))
|
||||
("randomseed", randomseed)
|
||||
("numshades", numshades) // is this really needed?
|
||||
("visibility", g_visibility)
|
||||
("parallaxtype", parallaxtype)
|
||||
("parallaxvisibility", parallaxvisibility)
|
||||
("parallaxyo", parallaxyoffs_override)
|
||||
("parallaxys", parallaxyscale_override)
|
||||
("pskybits", pskybits_override)
|
||||
("numsprites", Numsprites);
|
||||
|
||||
}
|
||||
void SaveEngineState()
|
||||
{
|
||||
auto fw = WriteSavegameChunk("engine.bin");
|
||||
fw->Write(sprite, sizeof(spritetype) * MAXSPRITES);
|
||||
WriteMagic(fw);
|
||||
fw->Write(headspritesect, sizeof(headspritesect));
|
||||
fw->Write(prevspritesect, sizeof(prevspritesect));
|
||||
fw->Write(nextspritesect, sizeof(nextspritesect));
|
||||
fw->Write(headspritestat, sizeof(headspritestat));
|
||||
fw->Write(prevspritestat, sizeof(prevspritestat));
|
||||
fw->Write(nextspritestat, sizeof(nextspritestat));
|
||||
WriteMagic(fw);
|
||||
for (int i = 0; i < MAXTILES; i++)
|
||||
{
|
||||
fw->Write(&picanm[i], sizeof(picanm[i]));
|
||||
}
|
||||
WriteMagic(fw);
|
||||
|
||||
|
||||
fw->Write(&tailspritefree, sizeof(tailspritefree));
|
||||
fw->Write(&myconnectindex, sizeof(myconnectindex));
|
||||
fw->Write(&connecthead, sizeof(connecthead));
|
||||
fw->Write(connectpoint2, sizeof(connectpoint2));
|
||||
fw->Write(&randomseed, sizeof(randomseed));
|
||||
fw->Write(&numshades, sizeof(numshades));
|
||||
fw->Write(&showinvisibility, sizeof(showinvisibility));
|
||||
WriteMagic(fw);
|
||||
|
||||
fw->Write(&g_visibility, sizeof(g_visibility));
|
||||
fw->Write(¶llaxtype, sizeof(parallaxtype));
|
||||
fw->Write(¶llaxvisibility, sizeof(parallaxvisibility));
|
||||
fw->Write(¶llaxyoffs_override, sizeof(parallaxyoffs_override));
|
||||
fw->Write(¶llaxyscale_override, sizeof(parallaxyscale_override));
|
||||
fw->Write(&pskybits_override, sizeof(pskybits_override));
|
||||
WriteMagic(fw);
|
||||
|
||||
fw->Write(&Numsprites, sizeof(Numsprites));
|
||||
sv_prespriteextsave();
|
||||
fw->Write(spriteext, sizeof(spriteext_t) * MAXSPRITES);
|
||||
fw->Write(&randomseed, sizeof(randomseed));
|
||||
sv_postspriteext();
|
||||
WriteMagic(fw);
|
||||
|
||||
}
|
||||
|
||||
void LoadEngineState()
|
||||
{
|
||||
auto fr = ReadSavegameChunk("engine.bin");
|
||||
if (fr.isOpen())
|
||||
{
|
||||
memset(sprite, 0, sizeof(sprite[0]) * MAXSPRITES);
|
||||
|
||||
fr.Read(sprite, sizeof(spritetype) * MAXSPRITES);
|
||||
CheckMagic(fr);
|
||||
fr.Read(headspritesect, sizeof(headspritesect));
|
||||
fr.Read(prevspritesect, sizeof(prevspritesect));
|
||||
fr.Read(nextspritesect, sizeof(nextspritesect));
|
||||
fr.Read(headspritestat, sizeof(headspritestat));
|
||||
fr.Read(prevspritestat, sizeof(prevspritestat));
|
||||
fr.Read(nextspritestat, sizeof(nextspritestat));
|
||||
CheckMagic(fr);
|
||||
for (int i = 0; i < MAXTILES; i++)
|
||||
if (arc.BeginArray("picanm")) // write this in the most compact form available.
|
||||
{
|
||||
fr.Read(&picanm[i], sizeof(picanm[i]));
|
||||
for (int i = 0; i < MAXTILES; i++)
|
||||
{
|
||||
arc(nullptr, picanm[i].sf)
|
||||
(nullptr, picanm[i].extra);
|
||||
}
|
||||
arc.EndArray();
|
||||
}
|
||||
CheckMagic(fr);
|
||||
|
||||
fr.Read(&tailspritefree, sizeof(tailspritefree));
|
||||
fr.Read(&myconnectindex, sizeof(myconnectindex));
|
||||
fr.Read(&connecthead, sizeof(connecthead));
|
||||
fr.Read(connectpoint2, sizeof(connectpoint2));
|
||||
fr.Read(&randomseed, sizeof(randomseed));
|
||||
fr.Read(&numshades, sizeof(numshades));
|
||||
fr.Read(&showinvisibility, sizeof(showinvisibility));
|
||||
CheckMagic(fr);
|
||||
arc.EndObject();
|
||||
}
|
||||
|
||||
fr.Read(&g_visibility, sizeof(g_visibility));
|
||||
fr.Read(¶llaxtype, sizeof(parallaxtype));
|
||||
fr.Read(¶llaxvisibility, sizeof(parallaxvisibility));
|
||||
fr.Read(¶llaxyoffs_override, sizeof(parallaxyoffs_override));
|
||||
fr.Read(¶llaxyscale_override, sizeof(parallaxyscale_override));
|
||||
fr.Read(&pskybits_override, sizeof(pskybits_override));
|
||||
CheckMagic(fr);
|
||||
|
||||
fr.Read(&Numsprites, sizeof(Numsprites));
|
||||
fr.Read(spriteext, sizeof(spriteext_t) * MAXSPRITES);
|
||||
fr.Read(&randomseed, sizeof(randomseed));
|
||||
sv_postspriteext();
|
||||
CheckMagic(fr);
|
||||
|
||||
fr.Close();
|
||||
// Undo the simplification.
|
||||
for (int i = 0; i < MAXSPRITES; i++)
|
||||
{
|
||||
if (nextspritestat[i] == -2) nextspritestat[i] = i + 1;
|
||||
if (nextspritesect[i] == -2) nextspritesect[i] = i + 1;
|
||||
if (prevspritestat[i] == -2) prevspritestat[i] = i - 1;
|
||||
if (prevspritesect[i] == -2) prevspritesect[i] = i - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle, bool formenu);
|
|||
void G_LoadGame(const char* filename);
|
||||
void G_SaveGame(const char* fn, const char* desc, bool ok4q, bool forceq);
|
||||
|
||||
void SaveEngineState();
|
||||
void LoadEngineState();
|
||||
void M_Autosave();
|
||||
|
||||
#define SAVEGAME_EXT ".dsave"
|
||||
|
|
|
@ -4632,7 +4632,7 @@ NewStateGroup(short SpriteNum, STATEp StateGroup[])
|
|||
|
||||
// Kind of a goofy check, but it should catch alot of invalid states!
|
||||
// BTW, 6144 is the max tile number allowed in editart.
|
||||
if (u->State && (u->State->Pic < 0 || u->State->Pic > 6144)) // JBF: verify this!
|
||||
if (u->State && (u->State->Pic < 0 || u->State->Pic > MAXTILES)) // JBF: verify this!
|
||||
return 0;
|
||||
|
||||
u->Rot = StateGroup;
|
||||
|
|
Loading…
Reference in a new issue