- 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)
: FCompressedFile (file, EWriting, true, false), m_ChunkID (id)

View File

@ -112,31 +112,6 @@ private:
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
{
public:

View File

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

View File

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

View File

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

View File

@ -196,7 +196,7 @@ void G_ClearSnapshots (void)
{
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
// 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;
F1Pic = "";
musicorder = 0;
snapshot = NULL;
Snapshot = { 0,0,0,0,nullptr };
snapshotVer = 0;
defered = 0;
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_WriteACSDefereds (FILE *file);
void G_SerializeLevel(FArchive &arc, bool hubLoad);
void G_SerializeLevel(FSerializer &arc, bool hubLoad);
#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] };
Reader->Seek(lmp->Position, SEEK_SET);
Reader->Read(cbuf.mBuffer, lmp->CompressedSize);
return cbuf;
}
//==========================================================================

View File

@ -13,6 +13,15 @@ struct FCompressedBuffer
char *mBuffer;
bool Decompress(char *destbuffer);
void Clean()
{
mSize = mCompressedSize = 0;
if (mBuffer != nullptr)
{
delete[] mBuffer;
mBuffer = nullptr;
}
}
};
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 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))
S_ChangeMusic (level.Music, level.musicorder);