mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 04:51:19 +00:00
- use FCompressedBuffer to store level snapshots. FCompressedMemFile has been removed.
This commit is contained in:
parent
da83d9e2bd
commit
075e98c967
11 changed files with 46 additions and 249 deletions
165
src/farchive.cpp
165
src/farchive.cpp
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -988,12 +988,3 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void G_SerializeLevel(FArchive &arc, bool hubLoad)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue