- use FCompressedBuffer to store level snapshots. FCompressedMemFile has been removed.

This commit is contained in:
Christoph Oelckers 2016-09-21 01:48:23 +02:00
parent da83d9e2bd
commit 075e98c967
11 changed files with 46 additions and 249 deletions

View file

@ -420,171 +420,6 @@ void FCompressedFile::Explode ()
} }
} }
FCompressedMemFile::FCompressedMemFile ()
{
m_SourceFromMem = false;
m_ImplodedBuffer = NULL;
}
/*
FCompressedMemFile::FCompressedMemFile (const char *name, EOpenMode mode)
: FCompressedFile (name, mode)
{
m_SourceFromMem = false;
m_ImplodedBuffer = NULL;
}
*/
FCompressedMemFile::~FCompressedMemFile ()
{
if (m_ImplodedBuffer != NULL)
{
M_Free (m_ImplodedBuffer);
}
}
bool FCompressedMemFile::Open (const char *name, EOpenMode mode)
{
if (mode == EWriting)
{
if (name)
{
I_Error ("FCompressedMemFile cannot write to disk");
}
else
{
return Open ();
}
}
else
{
bool res = FCompressedFile::Open (name, EReading);
if (res)
{
fclose (m_File);
m_File = NULL;
}
return res;
}
return false;
}
bool FCompressedMemFile::Open (void *memblock)
{
Close ();
m_Mode = EReading;
m_Buffer = (BYTE *)memblock;
m_SourceFromMem = true;
Explode ();
m_SourceFromMem = false;
return !!m_Buffer;
}
bool FCompressedMemFile::Open ()
{
Close ();
m_Mode = EWriting;
m_BufferSize = 0;
m_MaxBufferSize = 16384;
m_Buffer = (unsigned char *)M_Malloc (16384);
m_Pos = 0;
return true;
}
bool FCompressedMemFile::Reopen ()
{
if (m_Buffer == NULL && m_ImplodedBuffer)
{
m_Mode = EReading;
m_Buffer = m_ImplodedBuffer;
m_SourceFromMem = true;
try
{
Explode ();
}
catch(...)
{
// If we just leave things as they are, m_Buffer and m_ImplodedBuffer
// both point to the same memory block and both will try to free it.
m_Buffer = NULL;
m_SourceFromMem = false;
throw;
}
m_SourceFromMem = false;
return true;
}
return false;
}
void FCompressedMemFile::Close ()
{
if (m_Mode == EWriting)
{
Implode ();
m_ImplodedBuffer = m_Buffer;
m_Buffer = NULL;
}
}
void FCompressedMemFile::Serialize(FArchive &arc)
{
if (arc.IsStoring ())
{
if (m_ImplodedBuffer == NULL)
{
I_Error ("FCompressedMemFile must be compressed before storing");
}
arc.Write (ZSig, 4);
DWORD sizes[2];
sizes[0] = SWAP_DWORD (((DWORD *)m_ImplodedBuffer)[0]);
sizes[1] = SWAP_DWORD (((DWORD *)m_ImplodedBuffer)[1]);
arc.Write (m_ImplodedBuffer, (sizes[0] ? sizes[0] : sizes[1])+8);
}
else
{
Close ();
m_Mode = EReading;
char sig[4];
DWORD sizes[2] = { 0, 0 };
arc.Read (sig, 4);
if (sig[0] != ZSig[0] || sig[1] != ZSig[1] || sig[2] != ZSig[2] || sig[3] != ZSig[3])
I_Error ("Expected to extract a compressed file");
arc << sizes[0] << sizes[1];
DWORD len = sizes[0] == 0 ? sizes[1] : sizes[0];
m_Buffer = (BYTE *)M_Malloc (len+8);
((DWORD *)m_Buffer)[0] = SWAP_DWORD(sizes[0]);
((DWORD *)m_Buffer)[1] = SWAP_DWORD(sizes[1]);
arc.Read (m_Buffer+8, len);
m_ImplodedBuffer = m_Buffer;
m_Buffer = NULL;
m_Mode = EWriting;
}
}
bool FCompressedMemFile::IsOpen () const
{
return !!m_Buffer;
}
void FCompressedMemFile::GetSizes(unsigned int &compressed, unsigned int &uncompressed) const
{
if (m_ImplodedBuffer != NULL)
{
compressed = BigLong(*(unsigned int *)m_ImplodedBuffer);
uncompressed = BigLong(*(unsigned int *)(m_ImplodedBuffer + 4));
}
else
{
compressed = 0;
uncompressed = m_BufferSize;
}
}
FPNGChunkFile::FPNGChunkFile (FILE *file, DWORD id) FPNGChunkFile::FPNGChunkFile (FILE *file, DWORD id)
: FCompressedFile (file, EWriting, true, false), m_ChunkID (id) : FCompressedFile (file, EWriting, true, false), m_ChunkID (id)

View file

@ -112,31 +112,6 @@ private:
void BeEmpty (); void BeEmpty ();
}; };
class FCompressedMemFile : public FCompressedFile
{
public:
FCompressedMemFile ();
FCompressedMemFile (FILE *file); // Create for reading
~FCompressedMemFile ();
bool Open (const char *name, EOpenMode mode); // Works for reading only
bool Open (void *memblock); // Open for reading only
bool Open (); // Open for writing only
bool Reopen (); // Re-opens imploded file for reading only
void Close ();
bool IsOpen () const;
void GetSizes(unsigned int &one, unsigned int &two) const;
void Serialize(FArchive &arc);
protected:
bool FreeOnExplode () { return !m_SourceFromMem; }
private:
bool m_SourceFromMem;
unsigned char *m_ImplodedBuffer;
};
class FPNGChunkFile : public FCompressedFile class FPNGChunkFile : public FCompressedFile
{ {
public: public:

View file

@ -1970,11 +1970,7 @@ void G_DoLoadGame ()
NextSkill = next; NextSkill = next;
} }
if (level.info->snapshot != NULL) level.info->Snapshot.Clean();
{
delete level.info->snapshot;
level.info->snapshot = NULL;
}
BackupSaveName = savename; BackupSaveName = savename;
@ -2263,11 +2259,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
BackupSaveName = filename; BackupSaveName = filename;
// We don't need the snapshot any longer. // We don't need the snapshot any longer.
if (level.info->snapshot != NULL) level.info->Snapshot.Clean();
{
delete level.info->snapshot;
level.info->snapshot = NULL;
}
insave = false; insave = false;
I_FreezeTime(false); I_FreezeTime(false);

View file

@ -85,6 +85,7 @@
#include "r_renderer.h" #include "r_renderer.h"
#include "r_utility.h" #include "r_utility.h"
#include "p_spec.h" #include "p_spec.h"
#include "serializer.h"
#include "gi.h" #include "gi.h"
@ -822,7 +823,7 @@ void G_DoCompleted (void)
} }
else else
{ // Make sure we don't have a snapshot lying around from before. { // Make sure we don't have a snapshot lying around from before.
level.info->ClearSnapshot(); level.info->Snapshot.Clean();
} }
} }
else else
@ -1482,19 +1483,20 @@ void G_AirControlChanged ()
void G_SnapshotLevel () void G_SnapshotLevel ()
{ {
if (level.info->snapshot) level.info->Snapshot.Clean();
delete level.info->snapshot;
if (level.info->isValid()) if (level.info->isValid())
{ {
level.info->snapshotVer = SAVEVER; level.info->snapshotVer = SAVEVER;
level.info->snapshot = new FCompressedMemFile;
level.info->snapshot->Open ();
FArchive arc (*level.info->snapshot); FSerializer arc;
if (arc.OpenWriter())
{
SaveVersion = SAVEVER; SaveVersion = SAVEVER;
G_SerializeLevel(arc, false); G_SerializeLevel(arc, false);
level.info->Snapshot = arc.GetCompressedOutput();
}
} }
} }
@ -1507,18 +1509,18 @@ void G_SnapshotLevel ()
void G_UnSnapshotLevel (bool hubLoad) void G_UnSnapshotLevel (bool hubLoad)
{ {
if (level.info->snapshot == NULL) if (level.info->Snapshot.mBuffer == nullptr)
return; return;
if (level.info->isValid()) if (level.info->isValid())
{ {
SaveVersion = level.info->snapshotVer; SaveVersion = level.info->snapshotVer;
level.info->snapshot->Reopen (); FSerializer arc;
FArchive arc (*level.info->snapshot); if (!arc.OpenReader(&level.info->Snapshot)) return;
if (hubLoad)
arc.SetHubTravel (); //if (hubLoad) arc.SetHubTravel (); // no idea if this is still needed.
G_SerializeLevel (arc, hubLoad); G_SerializeLevel (arc, hubLoad);
arc.Close ();
level.FromSnapshot = true; level.FromSnapshot = true;
TThinkerIterator<APlayerPawn> it; TThinkerIterator<APlayerPawn> it;
@ -1548,7 +1550,7 @@ void G_UnSnapshotLevel (bool hubLoad)
} }
} }
// No reason to keep the snapshot around once the level's been entered. // No reason to keep the snapshot around once the level's been entered.
level.info->ClearSnapshot(); level.info->Snapshot.Clean();
if (hubLoad) if (hubLoad)
{ {
// Unlock ACS global strings that were locked when the snapshot was made. // Unlock ACS global strings that were locked when the snapshot was made.
@ -1564,7 +1566,7 @@ void G_UnSnapshotLevel (bool hubLoad)
static void writeSnapShot (FArchive &arc, level_info_t *i) static void writeSnapShot (FArchive &arc, level_info_t *i)
{ {
arc << i->snapshotVer << i->MapName; arc << i->snapshotVer << i->MapName;
i->snapshot->Serialize (arc); //i->snapshot->Serialize (arc);
} }
//========================================================================== //==========================================================================
@ -1576,6 +1578,7 @@ void G_WriteSnapshots (FILE *file)
{ {
unsigned int i; unsigned int i;
#if 0
for (i = 0; i < wadlevelinfos.Size(); i++) for (i = 0; i < wadlevelinfos.Size(); i++)
{ {
if (wadlevelinfos[i].snapshot) if (wadlevelinfos[i].snapshot)
@ -1589,6 +1592,7 @@ void G_WriteSnapshots (FILE *file)
FPNGChunkArchive arc (file, DSNP_ID); FPNGChunkArchive arc (file, DSNP_ID);
writeSnapShot(arc, &TheDefaultLevelInfo); writeSnapShot(arc, &TheDefaultLevelInfo);
} }
#endif
FPNGChunkArchive *arc = NULL; FPNGChunkArchive *arc = NULL;
@ -1662,8 +1666,10 @@ void G_ReadSnapshots (PNGHandle *png)
arc << MapName; arc << MapName;
i = FindLevelInfo (MapName); i = FindLevelInfo (MapName);
i->snapshotVer = snapver; i->snapshotVer = snapver;
#if 0
i->snapshot = new FCompressedMemFile; i->snapshot = new FCompressedMemFile;
i->snapshot->Serialize (arc); i->snapshot->Serialize (arc);
#endif
chunkLen = (DWORD)M_NextPNGChunk (png, SNAP_ID); chunkLen = (DWORD)M_NextPNGChunk (png, SNAP_ID);
} }
@ -1676,8 +1682,10 @@ void G_ReadSnapshots (PNGHandle *png)
arc << snapver; arc << snapver;
arc << MapName; arc << MapName;
TheDefaultLevelInfo.snapshotVer = snapver; TheDefaultLevelInfo.snapshotVer = snapver;
#if 0
TheDefaultLevelInfo.snapshot = new FCompressedMemFile; TheDefaultLevelInfo.snapshot = new FCompressedMemFile;
TheDefaultLevelInfo.snapshot->Serialize (arc); TheDefaultLevelInfo.snapshot->Serialize (arc);
#endif
} }
chunkLen = (DWORD)M_FindPNGChunk (png, VIST_ID); chunkLen = (DWORD)M_FindPNGChunk (png, VIST_ID);
@ -1727,12 +1735,10 @@ CCMD(listsnapshots)
{ {
for (unsigned i = 0; i < wadlevelinfos.Size(); ++i) for (unsigned i = 0; i < wadlevelinfos.Size(); ++i)
{ {
FCompressedMemFile *snapshot = wadlevelinfos[i].snapshot; FCompressedBuffer *snapshot = &wadlevelinfos[i].Snapshot;
if (snapshot != NULL) if (snapshot->mBuffer != nullptr)
{ {
unsigned int comp, uncomp; Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].MapName.GetChars(), snapshot->mCompressedSize, snapshot->mSize);
snapshot->GetSizes(comp, uncomp);
Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].MapName.GetChars(), comp, uncomp);
} }
} }
} }

View file

@ -39,6 +39,7 @@
#include "sc_man.h" #include "sc_man.h"
#include "s_sound.h" #include "s_sound.h"
#include "textures/textures.h" #include "textures/textures.h"
#include "resourcefiles/file_zip.h"
struct level_info_t; struct level_info_t;
struct cluster_info_t; struct cluster_info_t;
@ -232,7 +233,6 @@ struct FSpecialAction
int Args[5]; // must allow 16 bit tags for 666 & 667! int Args[5]; // must allow 16 bit tags for 666 & 667!
}; };
class FCompressedMemFile;
class DScroller; class DScroller;
class FScanner; class FScanner;
@ -295,7 +295,7 @@ struct level_info_t
FString LevelName; FString LevelName;
SBYTE WallVertLight, WallHorizLight; SBYTE WallVertLight, WallHorizLight;
int musicorder; int musicorder;
FCompressedMemFile *snapshot; FCompressedBuffer Snapshot;
DWORD snapshotVer; DWORD snapshotVer;
struct acsdefered_t *defered; struct acsdefered_t *defered;
float skyspeed1; float skyspeed1;
@ -346,13 +346,12 @@ struct level_info_t
} }
~level_info_t() ~level_info_t()
{ {
ClearSnapshot(); Snapshot.Clean();
ClearDefered(); ClearDefered();
} }
void Reset(); void Reset();
bool isValid(); bool isValid();
FString LookupLevelName (); FString LookupLevelName ();
void ClearSnapshot();
void ClearDefered(); void ClearDefered();
level_info_t *CheckLevelRedirect (); level_info_t *CheckLevelRedirect ();

View file

@ -196,7 +196,7 @@ void G_ClearSnapshots (void)
{ {
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++) for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{ {
wadlevelinfos[i].ClearSnapshot(); wadlevelinfos[i].Snapshot.Clean();
} }
// Since strings are only locked when snapshotting a level, unlock them // Since strings are only locked when snapshotting a level, unlock them
// all now, since we got rid of all the snapshots that cared about them. // all now, since we got rid of all the snapshots that cared about them.
@ -248,7 +248,7 @@ void level_info_t::Reset()
WallVertLight = +8; WallVertLight = +8;
F1Pic = ""; F1Pic = "";
musicorder = 0; musicorder = 0;
snapshot = NULL; Snapshot = { 0,0,0,0,nullptr };
snapshotVer = 0; snapshotVer = 0;
defered = 0; defered = 0;
skyspeed1 = skyspeed2 = 0.f; skyspeed1 = skyspeed2 = 0.f;
@ -334,17 +334,6 @@ FString level_info_t::LookupLevelName()
} }
//==========================================================================
//
//
//==========================================================================
void level_info_t::ClearSnapshot()
{
if (snapshot != NULL) delete snapshot;
snapshot = NULL;
}
//========================================================================== //==========================================================================
// //
// //

View file

@ -988,12 +988,3 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
} }
//==========================================================================
//
//
//==========================================================================
void G_SerializeLevel(FArchive &arc, bool hubLoad)
{
}

View file

@ -45,6 +45,6 @@ void P_DestroyThinkers(bool hubLoad);
void P_ReadACSDefereds (PNGHandle *png); void P_ReadACSDefereds (PNGHandle *png);
void P_WriteACSDefereds (FILE *file); void P_WriteACSDefereds (FILE *file);
void G_SerializeLevel(FArchive &arc, bool hubLoad); void G_SerializeLevel(FSerializer &arc, bool hubLoad);
#endif // __P_SAVEG_H__ #endif // __P_SAVEG_H__

View file

@ -314,6 +314,7 @@ FCompressedBuffer FZipFile::GetRawLump(int lumpnum)
FCompressedBuffer cbuf = { (unsigned)lmp->LumpSize, (unsigned)lmp->CompressedSize, lmp->Method, lmp->GPFlags, new char[lmp->CompressedSize] }; FCompressedBuffer cbuf = { (unsigned)lmp->LumpSize, (unsigned)lmp->CompressedSize, lmp->Method, lmp->GPFlags, new char[lmp->CompressedSize] };
Reader->Seek(lmp->Position, SEEK_SET); Reader->Seek(lmp->Position, SEEK_SET);
Reader->Read(cbuf.mBuffer, lmp->CompressedSize); Reader->Read(cbuf.mBuffer, lmp->CompressedSize);
return cbuf;
} }
//========================================================================== //==========================================================================

View file

@ -13,6 +13,15 @@ struct FCompressedBuffer
char *mBuffer; char *mBuffer;
bool Decompress(char *destbuffer); bool Decompress(char *destbuffer);
void Clean()
{
mSize = mCompressedSize = 0;
if (mBuffer != nullptr)
{
delete[] mBuffer;
mBuffer = nullptr;
}
}
}; };
enum enum

View file

@ -446,7 +446,7 @@ void S_Start ()
// Don't start the music if loading a savegame, because the music is stored there. // Don't start the music if loading a savegame, because the music is stored there.
// Don't start the music if revisiting a level in a hub for the same reason. // Don't start the music if revisiting a level in a hub for the same reason.
if (!savegamerestore && (level.info == NULL || level.info->snapshot == NULL || !level.info->isValid())) if (!savegamerestore && (level.info == nullptr || level.info->Snapshot.mBuffer == nullptr || !level.info->isValid()))
{ {
if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid)) if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid))
S_ChangeMusic (level.Music, level.musicorder); S_ChangeMusic (level.Music, level.musicorder);