diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94f7c9ab3..d6878a19e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1038,7 +1038,6 @@ set (PCH_SOURCES dthinker.cpp edata.cpp f_wipe.cpp - farchive.cpp files.cpp g_doomedmap.cpp g_game.cpp diff --git a/src/dobject.cpp b/src/dobject.cpp index aa874d747..b5af56151 100644 --- a/src/dobject.cpp +++ b/src/dobject.cpp @@ -47,7 +47,6 @@ #include "stats.h" #include "a_sharedglobal.h" #include "dsectoreffect.h" -#include "farchive.h" #include "serializer.h" //========================================================================== diff --git a/src/dthinker.cpp b/src/dthinker.cpp index 0e57f05cf..3cb40cb8f 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -38,7 +38,6 @@ #include "statnums.h" #include "i_system.h" #include "doomerrors.h" -#include "farchive.h" #include "serializer.h" #include "d_player.h" diff --git a/src/farchive.cpp b/src/farchive.cpp deleted file mode 100644 index 3d57e4f71..000000000 --- a/src/farchive.cpp +++ /dev/null @@ -1,987 +0,0 @@ -/* -** farchive.cpp -** Implements an archiver for DObject serialization. -** -**--------------------------------------------------------------------------- -** Copyright 1998-2009 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** The structure of the archive file generated is influenced heavily by the -** description of the MFC archive format published somewhere in the MSDN -** library. -** -** Two major shortcomings of the format I use are that there is no version -** control and no support for storing the non-default portions of objects. -** The latter would allow for easier extension of objects in future -** releases even without a versioning system. -*/ - -#include -#include -#include -#include - -#include "doomtype.h" -#include "farchive.h" -#include "m_swap.h" -#include "m_crc32.h" -#include "cmdlib.h" -#include "i_system.h" -#include "c_cvars.h" -#include "c_dispatch.h" -#include "d_player.h" -#include "m_misc.h" -#include "dobject.h" - -// These are special tokens found in the data stream of an archive. -// Whenever a new object is encountered, it gets created using new and -// is then asked to serialize itself before processing of the previous -// object continues. This can result in some very deep recursion if -// you aren't careful about how you organize your data. - -#define NEW_OBJ ((BYTE)1) // Data for a new object follows -#define NEW_CLS_OBJ ((BYTE)2) // Data for a new class and object follows -#define OLD_OBJ ((BYTE)3) // Reference to an old object follows -#define NULL_OBJ ((BYTE)4) // Load as NULL -#define M1_OBJ ((BYTE)44) // Load as (DObject*)-1 - -#define NEW_PLYR_OBJ ((BYTE)5) // Data for a new player follows -#define NEW_PLYR_CLS_OBJ ((BYTE)6) // Data for a new class and player follows - -#define NEW_NAME ((BYTE)27) // A new name follows -#define OLD_NAME ((BYTE)28) // Reference to an old name follows -#define NIL_NAME ((BYTE)33) // Load as NULL - -#define NEW_SPRITE ((BYTE)11) // A new sprite name follows -#define OLD_SPRITE ((BYTE)12) // Reference to an old sprite name follows - -#ifdef __BIG_ENDIAN__ -static inline WORD SWAP_WORD(WORD x) { return x; } -static inline DWORD SWAP_DWORD(DWORD x) { return x; } -static inline QWORD SWAP_QWORD(QWORD x) { return x; } -static inline void SWAP_FLOAT(float x) { } -static inline void SWAP_DOUBLE(double &dst, double src) { dst = src; } -#else -#ifdef _MSC_VER -static inline WORD SWAP_WORD(WORD x) { return _byteswap_ushort(x); } -static inline DWORD SWAP_DWORD(DWORD x) { return _byteswap_ulong(x); } -static inline QWORD SWAP_QWORD(QWORD x) { return _byteswap_uint64(x); } -static inline void SWAP_DOUBLE(double &dst, double &src) -{ - union twiddle { QWORD q; double d; } tdst, tsrc; - tsrc.d = src; - tdst.q = _byteswap_uint64(tsrc.q); - dst = tdst.d; -} -#else -static inline WORD SWAP_WORD(WORD x) { return (((x)<<8) | ((x)>>8)); } -static inline DWORD SWAP_DWORD(DWORD x) { return x = (((x)>>24) | (((x)>>8)&0xff00) | (((x)<<8)&0xff0000) | ((x)<<24)); } -static inline QWORD SWAP_QWORD(QWORD x) -{ - union { QWORD q; DWORD d[2]; } t, u; - t.q = x; - u.d[0] = SWAP_DWORD(t.d[1]); - u.d[1] = SWAP_DWORD(t.d[0]); - return u.q; -} -static inline void SWAP_DOUBLE(double &dst, double &src) -{ - union twiddle { double f; DWORD d[2]; } tdst, tsrc; - DWORD t; - - tsrc.f = src; - t = tsrc.d[0]; - tdst.d[0] = SWAP_DWORD(tsrc.d[1]); - tdst.d[1] = SWAP_DWORD(t); - dst = tdst.f; -} -#endif -static inline void SWAP_FLOAT(float &x) -{ - union twiddle { DWORD i; float f; } t; - t.f = x; - t.i = SWAP_DWORD(t.i); - x = t.f; -} -#endif - -// Output buffer size for compression; need some extra space. -// I assume the description in zlib.h is accurate. -#define OUT_LEN(a) ((a) + (a) / 1000 + 12) - -void FCompressedFile::BeEmpty () -{ - m_Pos = 0; - m_BufferSize = 0; - m_MaxBufferSize = 0; - m_Buffer = NULL; - m_File = NULL; - m_NoCompress = false; - m_Mode = ENotOpen; -} - -static const char LZOSig[4] = { 'F', 'L', 'Z', 'O' }; -static const char ZSig[4] = { 'F', 'L', 'Z', 'L' }; - -FCompressedFile::FCompressedFile () -{ - BeEmpty (); -} - -FCompressedFile::FCompressedFile (const char *name, EOpenMode mode, bool dontCompress) -{ - BeEmpty (); - Open (name, mode); - m_NoCompress = dontCompress; -} - -FCompressedFile::FCompressedFile (FILE *file, EOpenMode mode, bool dontCompress, bool postopen) -{ - BeEmpty (); - m_Mode = mode; - m_File = file; - m_NoCompress = dontCompress; - if (postopen) - { - PostOpen (); - } -} - -FCompressedFile::~FCompressedFile () -{ - Close (); -} - -bool FCompressedFile::Open (const char *name, EOpenMode mode) -{ - Close (); - if (name == NULL) - return false; - m_Mode = mode; - m_File = fopen (name, mode == EReading ? "rb" : "wb"); - PostOpen (); - return !!m_File; -} - -void FCompressedFile::PostOpen () -{ - if (m_File && m_Mode == EReading) - { - char sig[4]; - fread (sig, 4, 1, m_File); - if (sig[0] != ZSig[0] || sig[1] != ZSig[1] || sig[2] != ZSig[2] || sig[3] != ZSig[3]) - { - fclose (m_File); - m_File = NULL; - if (sig[0] == LZOSig[0] && sig[1] == LZOSig[1] && sig[2] == LZOSig[2] && sig[3] == LZOSig[3]) - { - Printf ("Compressed files from older ZDooms are not supported.\n"); - } - return; - } - else - { - DWORD sizes[2]; - fread (sizes, sizeof(DWORD), 2, m_File); - sizes[0] = SWAP_DWORD (sizes[0]); - sizes[1] = SWAP_DWORD (sizes[1]); - unsigned int len = sizes[0] == 0 ? sizes[1] : sizes[0]; - m_Buffer = (BYTE *)M_Malloc (len+8); - fread (m_Buffer+8, len, 1, m_File); - sizes[0] = SWAP_DWORD (sizes[0]); - sizes[1] = SWAP_DWORD (sizes[1]); - ((DWORD *)m_Buffer)[0] = sizes[0]; - ((DWORD *)m_Buffer)[1] = sizes[1]; - Explode (); - } - } -} - -void FCompressedFile::Close () -{ - if (m_File) - { - if (m_Mode == EWriting) - { - Implode (); - fwrite (ZSig, 4, 1, m_File); - fwrite (m_Buffer, m_BufferSize + 8, 1, m_File); - } - fclose (m_File); - m_File = NULL; - } - if (m_Buffer) - { - M_Free (m_Buffer); - m_Buffer = NULL; - } - BeEmpty (); -} - -void FCompressedFile::Flush () -{ -} - -FFile::EOpenMode FCompressedFile::Mode () const -{ - return m_Mode; -} - -bool FCompressedFile::IsOpen () const -{ - return !!m_File; -} - -FFile &FCompressedFile::Write (const void *mem, unsigned int len) -{ - if (m_Mode == EWriting) - { - if (m_Pos + len > m_MaxBufferSize) - { - do - { - m_MaxBufferSize = m_MaxBufferSize ? m_MaxBufferSize * 2 : 16384; - } - while (m_Pos + len > m_MaxBufferSize); - m_Buffer = (BYTE *)M_Realloc (m_Buffer, m_MaxBufferSize); - } - if (len == 1) - m_Buffer[m_Pos] = *(BYTE *)mem; - else - memcpy (m_Buffer + m_Pos, mem, len); - m_Pos += len; - if (m_Pos > m_BufferSize) - m_BufferSize = m_Pos; - } - else - { - I_Error ("Tried to write to reading cfile"); - } - return *this; -} - -FFile &FCompressedFile::Read (void *mem, unsigned int len) -{ - if (m_Mode == EReading) - { - if (m_Pos + len > m_BufferSize) - { - I_Error ("Attempt to read past end of cfile"); - } - if (len == 1) - *(BYTE *)mem = m_Buffer[m_Pos]; - else - memcpy (mem, m_Buffer + m_Pos, len); - m_Pos += len; - } - else - { - I_Error ("Tried to read from writing cfile"); - } - return *this; -} - -unsigned int FCompressedFile::Tell () const -{ - return m_Pos; -} - -FFile &FCompressedFile::Seek (int pos, ESeekPos ofs) -{ - if (ofs == ESeekRelative) - pos += m_Pos; - else if (ofs == ESeekEnd) - pos = m_BufferSize - pos; - - if (pos < 0) - m_Pos = 0; - else if ((unsigned)pos > m_BufferSize) - m_Pos = m_BufferSize; - else - m_Pos = pos; - - return *this; -} - -CVAR (Bool, nofilecompression, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -void FCompressedFile::Implode () -{ - uLong outlen; - uLong len = m_BufferSize; - Byte *compressed = NULL; - BYTE *oldbuf = m_Buffer; - int r; - - if (!nofilecompression && !m_NoCompress) - { - outlen = OUT_LEN(len); - do - { - compressed = new Bytef[outlen]; - r = compress (compressed, &outlen, m_Buffer, len); - if (r == Z_BUF_ERROR) - { - delete[] compressed; - outlen += 1024; - } - } while (r == Z_BUF_ERROR); - - // If the data could not be compressed, store it as-is. - if (r != Z_OK || outlen >= len) - { - DPrintf (DMSG_SPAMMY, "cfile could not be compressed\n"); - outlen = 0; - } - else - { - DPrintf (DMSG_SPAMMY, "cfile shrank from %lu to %lu bytes\n", len, outlen); - } - } - else - { - outlen = 0; - } - - m_MaxBufferSize = m_BufferSize = ((outlen == 0) ? len : outlen); - m_Buffer = (BYTE *)M_Malloc (m_BufferSize + 8); - m_Pos = 0; - - DWORD *lens = (DWORD *)(m_Buffer); - lens[0] = BigLong((unsigned int)outlen); - lens[1] = BigLong((unsigned int)len); - - if (outlen == 0) - memcpy (m_Buffer + 8, oldbuf, len); - else - memcpy (m_Buffer + 8, compressed, outlen); - if (compressed) - delete[] compressed; - M_Free (oldbuf); -} - -void FCompressedFile::Explode () -{ - uLong expandsize, cprlen; - unsigned char *expand; - - if (m_Buffer) - { - unsigned int *ints = (unsigned int *)(m_Buffer); - cprlen = BigLong(ints[0]); - expandsize = BigLong(ints[1]); - - expand = (unsigned char *)M_Malloc (expandsize); - if (cprlen) - { - int r; - uLong newlen; - - newlen = expandsize; - r = uncompress (expand, &newlen, m_Buffer + 8, cprlen); - if (r != Z_OK || newlen != expandsize) - { - M_Free (expand); - I_Error ("Could not decompress buffer: %s", M_ZLibError(r).GetChars()); - } - } - else - { - memcpy (expand, m_Buffer + 8, expandsize); - } - if (FreeOnExplode ()) - M_Free (m_Buffer); - m_Buffer = expand; - m_BufferSize = expandsize; - } -} - - -FPNGChunkFile::FPNGChunkFile (FILE *file, DWORD id) - : FCompressedFile (file, EWriting, true, false), m_ChunkID (id) -{ -} - -FPNGChunkFile::FPNGChunkFile (FILE *file, DWORD id, size_t chunklen) - : FCompressedFile (file, EReading, true, false), m_ChunkID (id) -{ - m_Buffer = (BYTE *)M_Malloc (chunklen); - m_BufferSize = (unsigned int)chunklen; - fread (m_Buffer, chunklen, 1, m_File); - // Skip the CRC for now. Maybe later it will be used. - fseek (m_File, 4, SEEK_CUR); -} - -// Unlike FCompressedFile::Close, m_File is left open -void FPNGChunkFile::Close () -{ - DWORD data[2]; - DWORD crc; - - if (m_File) - { - if (m_Mode == EWriting) - { - crc = CalcCRC32 ((BYTE *)&m_ChunkID, 4); - crc = AddCRC32 (crc, (BYTE *)m_Buffer, m_BufferSize); - - data[0] = BigLong(m_BufferSize); - data[1] = m_ChunkID; - fwrite (data, 8, 1, m_File); - fwrite (m_Buffer, m_BufferSize, 1, m_File); - crc = SWAP_DWORD (crc); - fwrite (&crc, 4, 1, m_File); - } - m_File = NULL; - } - FCompressedFile::Close (); -} - -FPNGChunkArchive::FPNGChunkArchive (FILE *file, DWORD id) - : FArchive (), Chunk (file, id) -{ - AttachToFile (Chunk); -} - -FPNGChunkArchive::FPNGChunkArchive (FILE *file, DWORD id, size_t len) - : FArchive (), Chunk (file, id, len) -{ - AttachToFile (Chunk); -} - -FPNGChunkArchive::~FPNGChunkArchive () -{ - // Close before FArchive's destructor, because Chunk will be - // destroyed before the FArchive is destroyed. - Close (); -} - -//============================================ -// -// FArchive -// -//============================================ - -FArchive::FArchive () -{ -} - -FArchive::FArchive (FFile &file) -{ - AttachToFile (file); -} - -void FArchive::AttachToFile (FFile &file) -{ - m_HubTravel = false; - m_File = &file; - if (file.Mode() == FFile::EReading) - { - m_Loading = true; - m_Storing = false; - } - else - { - m_Loading = false; - m_Storing = true; - } - m_Persistent = file.IsPersistent(); - - ClassToArchive.Clear(); - ArchiveToClass.Clear(); - - ObjectToArchive.Clear(); - ArchiveToObject.Clear(); - - memset(m_NameHash, 0xFF, sizeof(m_NameHash)); - m_Names.Clear(); - m_NameStorage.Clear(); - - m_NumSprites = 0; - m_SpriteMap = new int[sprites.Size()]; - for (size_t s = 0; s < sprites.Size(); ++s) - { - m_SpriteMap[s] = -1; - } -} - -FArchive::~FArchive () -{ - Close (); - if (m_SpriteMap) - delete[] m_SpriteMap; -} - -void FArchive::Write (const void *mem, unsigned int len) -{ - m_File->Write (mem, len); -} - -void FArchive::Read (void *mem, unsigned int len) -{ - m_File->Read (mem, len); -} - -void FArchive::Close () -{ - if (m_File) - { - m_File->Close (); - m_File = NULL; - DPrintf (DMSG_SPAMMY, "Processed %u objects\n", ArchiveToObject.Size()); - } -} - -void FArchive::WriteByte(BYTE val) -{ - m_File->Write(&val, 1); -} - -void FArchive::WriteInt16(WORD val) -{ - WORD out = SWAP_WORD(val); - m_File->Write(&out, 2); -} - -void FArchive::WriteInt32(DWORD val) -{ - int out = SWAP_DWORD(val); - m_File->Write(&out, 4); -} - -void FArchive::WriteInt64(QWORD val) -{ - long long out = SWAP_QWORD(val); - m_File->Write(&out, 8); -} - -void FArchive::WriteCount (DWORD count) -{ - BYTE out; - - do - { - out = count & 0x7f; - if (count >= 0x80) - out |= 0x80; - Write (&out, sizeof(BYTE)); - count >>= 7; - } while (count); - -} - -DWORD FArchive::ReadCount () -{ - BYTE in; - DWORD count = 0; - int ofs = 0; - - do - { - Read (&in, sizeof(BYTE)); - count |= (in & 0x7f) << ofs; - ofs += 7; - } while (in & 0x80); - - return count; -} - -void FArchive::WriteName (const char *name) -{ - BYTE id; - - if (name == NULL) - { - id = NIL_NAME; - Write (&id, 1); - } - else - { - DWORD index = FindName (name); - if (index != NameMap::NO_INDEX) - { - id = OLD_NAME; - Write (&id, 1); - WriteCount (index); - } - else - { - AddName (name); - id = NEW_NAME; - Write (&id, 1); - WriteString (name); - } - } -} - -const char *FArchive::ReadName () -{ - BYTE id; - - operator<< (id); - if (id == NIL_NAME) - { - return NULL; - } - else if (id == OLD_NAME) - { - DWORD index = ReadCount (); - if (index >= m_Names.Size()) - { - I_Error ("Name %u has not been read yet\n", index); - } - return &m_NameStorage[m_Names[index].StringStart]; - } - else if (id == NEW_NAME) - { - DWORD index; - DWORD size = ReadCount (); - char *str; - - index = (DWORD)m_NameStorage.Reserve (size); - str = &m_NameStorage[index]; - Read (str, size-1); - str[size-1] = 0; - AddName (index); - return str; - } - else - { - I_Error ("Expected a name but got something else\n"); - return NULL; - } -} - -void FArchive::WriteString (const char *str) -{ - if (str == NULL) - { - WriteCount (0); - } - else - { - DWORD size = (DWORD)(strlen (str) + 1); - WriteCount (size); - Write (str, size - 1); - } -} - -void FArchive::WriteString(const FString &str) -{ - // The count includes the '\0' terminator, but we don't - // actually write it out. - WriteCount(DWORD(str.Len() + 1)); - Write(str, DWORD(str.Len())); -} - -FArchive &FArchive::operator<< (char *&str) -{ - if (m_Storing) - { - WriteString (str); - } - else - { - DWORD size = ReadCount (); - char *str2; - - if (size == 0) - { - str2 = NULL; - } - else - { - str2 = new char[size]; - size--; - Read (str2, size); - str2[size] = 0; - ReplaceString ((char **)&str, str2); - } - if (str) - { - delete[] str; - } - str = str2; - } - return *this; -} - -FArchive &FArchive::operator<< (FString &str) -{ - if (m_Storing) - { - WriteString (str); - } - else - { - DWORD size = ReadCount(); - - if (size == 0) - { - str = ""; - } - else - { - char *str2 = (char *)alloca(size*sizeof(char)); - size--; - Read (str2, size); - str = FString(str2, size); - } - } - return *this; -} - -FArchive &FArchive::operator<< (BYTE &c) -{ - if (m_Storing) - Write (&c, sizeof(BYTE)); - else - Read (&c, sizeof(BYTE)); - return *this; -} - -FArchive &FArchive::operator<< (WORD &w) -{ - if (m_Storing) - { - WORD temp = SWAP_WORD(w); - Write (&temp, sizeof(WORD)); - } - else - { - Read (&w, sizeof(WORD)); - w = SWAP_WORD(w); - } - return *this; -} - -FArchive &FArchive::operator<< (DWORD &w) -{ - if (m_Storing) - { - DWORD temp = SWAP_DWORD(w); - Write (&temp, sizeof(DWORD)); - } - else - { - Read (&w, sizeof(DWORD)); - w = SWAP_DWORD(w); - } - return *this; -} - -FArchive &FArchive::operator<< (QWORD &w) -{ - if (m_Storing) - { - QWORD temp = SWAP_QWORD(w); - Write (&temp, sizeof(QWORD)); - } - else - { - Read (&w, sizeof(QWORD)); - w = SWAP_QWORD(w); - } - return *this; -} - -FArchive &FArchive::operator<< (float &w) -{ - if (m_Storing) - { - float temp = w; - SWAP_FLOAT(temp); - Write (&temp, sizeof(float)); - } - else - { - Read (&w, sizeof(float)); - SWAP_FLOAT(w); - } - return *this; -} - -FArchive &FArchive::operator<< (double &w) -{ - if (m_Storing) - { - double temp; - SWAP_DOUBLE(temp,w); - Write (&temp, sizeof(double)); - } - else - { - Read (&w, sizeof(double)); - SWAP_DOUBLE(w,w); - } - return *this; -} - -FArchive &FArchive::operator<< (FName &n) -{ // In an archive, a "name" is a string that might be stored multiple times, - // so it is only stored once. It is still treated as a normal string. In the - // rest of the game, a name is a unique identifier for a number. - if (m_Storing) - { - WriteName (n.GetChars()); - } - else - { - n = FName(ReadName()); - } - return *this; -} - -DWORD FArchive::AddName (const char *name) -{ - DWORD index; - unsigned int hash = MakeKey (name) % EObjectHashSize; - - index = FindName (name, hash); - if (index == NameMap::NO_INDEX) - { - DWORD namelen = (DWORD)(strlen (name) + 1); - DWORD strpos = (DWORD)m_NameStorage.Reserve (namelen); - NameMap mapper = { strpos, (DWORD)m_NameHash[hash] }; - - memcpy (&m_NameStorage[strpos], name, namelen); - m_NameHash[hash] = index = (DWORD)m_Names.Push (mapper); - } - return index; -} - -DWORD FArchive::AddName (unsigned int start) -{ - DWORD hash = MakeKey (&m_NameStorage[start]) % EObjectHashSize; - NameMap mapper = { (DWORD)start, (DWORD)m_NameHash[hash] }; - return (DWORD)(m_NameHash[hash] = m_Names.Push (mapper)); -} - -DWORD FArchive::FindName (const char *name) const -{ - return FindName (name, MakeKey (name) % EObjectHashSize); -} - -DWORD FArchive::FindName (const char *name, unsigned int bucket) const -{ - unsigned int map = m_NameHash[bucket]; - - while (map != NameMap::NO_INDEX) - { - const NameMap *mapping = &m_Names[map]; - if (strcmp (name, &m_NameStorage[mapping->StringStart]) == 0) - { - return (DWORD)map; - } - map = mapping->HashNext; - } - return (DWORD)map; -} - -DWORD FArchive::WriteClass (PClass *info) -{ - if (ClassToArchive.CheckKey(info) != NULL) - { - I_Error ("Attempt to write '%s' twice.\n", info->TypeName.GetChars()); - } - DWORD index = ArchiveToClass.Push(info); - ClassToArchive[info] = index; - WriteString (info->TypeName.GetChars()); - return index; -} - -PClass *FArchive::ReadClass () -{ - struct String { - String() { val = NULL; } - ~String() { if (val) delete[] val; } - char *val; - } typeName; - - operator<< (typeName.val); - FName zaname(typeName.val, true); - if (zaname != NAME_None) - { - PClass *type = PClass::FindClass(zaname); - if (type != NULL) - { - ClassToArchive[type] = ArchiveToClass.Push(type); - return type; - } - } - I_Error ("Unknown class '%s'\n", typeName.val); - return NULL; -} - -PClass *FArchive::ReadClass (const PClass *wanttype) -{ - PClass *type = ReadClass (); - if (!type->IsDescendantOf (wanttype)) - { - I_Error ("Expected to extract an object of type '%s'.\n" - "Found one of type '%s' instead.\n", - wanttype->TypeName.GetChars(), type->TypeName.GetChars()); - } - return type; -} - -PClass *FArchive::ReadStoredClass (const PClass *wanttype) -{ - DWORD index = ReadCount (); - PClass *type = ArchiveToClass[index]; - if (!type->IsDescendantOf (wanttype)) - { - I_Error ("Expected to extract an object of type '%s'.\n" - "Found one of type '%s' instead.\n", - wanttype->TypeName.GetChars(), type->TypeName.GetChars()); - } - return type; -} - - -void FArchive::UserReadClass (PClass *&type) -{ - BYTE newclass; - - Read (&newclass, 1); - switch (newclass) - { - case 0: - type = ReadStoredClass (RUNTIME_CLASS(DObject)); - break; - case 1: - type = ReadClass (); - break; - case 2: - type = NULL; - break; - default: - I_Error ("Unknown class type %d in archive.\n", newclass); - break; - } -} - diff --git a/src/farchive.h b/src/farchive.h deleted file mode 100644 index ee0310898..000000000 --- a/src/farchive.h +++ /dev/null @@ -1,253 +0,0 @@ -/* -** farchive.h -** -**--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef __FARCHIVE_H__ -#define __FARCHIVE_H__ - -#include -#include "dobject.h" -#include "r_state.h" -#include "tflags.h" - -class FFile -{ -public: - enum EOpenMode - { - EReading, - EWriting, - ENotOpen - }; - - enum ESeekPos - { - ESeekSet, - ESeekRelative, - ESeekEnd - }; - -virtual ~FFile () {} - -virtual bool Open (const char *name, EOpenMode mode) = 0; -virtual void Close () = 0; -virtual void Flush () = 0; -virtual EOpenMode Mode () const = 0; -virtual bool IsPersistent () const = 0; -virtual bool IsOpen () const = 0; - -virtual FFile& Write (const void *, unsigned int) = 0; -virtual FFile& Read (void *, unsigned int) = 0; - -virtual unsigned int Tell () const = 0; -virtual FFile& Seek (int, ESeekPos) = 0; -inline FFile& Seek (unsigned int i, ESeekPos p) { return Seek ((int)i, p); } -}; - -class FCompressedFile : public FFile -{ -public: - FCompressedFile (); - FCompressedFile (const char *name, EOpenMode mode, bool dontcompress = false); - FCompressedFile (FILE *file, EOpenMode mode, bool dontcompress = false, bool postopen=true); - ~FCompressedFile (); - - bool Open (const char *name, EOpenMode mode); - void Close (); - void Flush (); - EOpenMode Mode () const; - bool IsPersistent () const { return true; } - bool IsOpen () const; - unsigned int GetSize () const { return m_BufferSize; } - - FFile &Write (const void *, unsigned int); - FFile &Read (void *, unsigned int); - unsigned int Tell () const; - FFile &Seek (int, ESeekPos); - -protected: - unsigned int m_Pos; - unsigned int m_BufferSize; - unsigned int m_MaxBufferSize; - unsigned char *m_Buffer; - bool m_NoCompress; - EOpenMode m_Mode; - FILE *m_File; - - void Implode (); - void Explode (); - virtual bool FreeOnExplode () { return true; } - void PostOpen (); - -private: - void BeEmpty (); -}; - -class FPNGChunkFile : public FCompressedFile -{ -public: - FPNGChunkFile (FILE *file, DWORD id); // Create for writing - FPNGChunkFile (FILE *file, DWORD id, size_t chunklen); // Create for reading - - void Close (); - -private: - DWORD m_ChunkID; -}; - -class FArchive -{ -public: - FArchive (FFile &file); - virtual ~FArchive (); - - inline bool IsLoading () const { return m_Loading; } - inline bool IsStoring () const { return m_Storing; } - inline bool IsPeristent () const { return m_Persistent; } - - void SetHubTravel () { m_HubTravel = true; } - - void Close (); - -virtual void Write (const void *mem, unsigned int len); -virtual void Read (void *mem, unsigned int len); - - void WriteString(const FString &str); - void WriteString (const char *str); - - void WriteByte(BYTE val); - void WriteInt16(WORD val); - void WriteInt32(DWORD val); - void WriteInt64(QWORD val); - - void WriteCount (DWORD count); - DWORD ReadCount (); - - void UserReadClass (PClass *&info); - template void UserReadClass(T *&info) - { - PClass *myclass; - UserReadClass(myclass); - info = dyn_cast(myclass); - } - - FArchive& operator<< (BYTE &c); - FArchive& operator<< (WORD &s); - FArchive& operator<< (DWORD &i); - FArchive& operator<< (QWORD &i); - FArchive& operator<< (QWORD_UNION &i) { return operator<< (i.AsOne); } - FArchive& operator<< (float &f); - FArchive& operator<< (double &d); - FArchive& operator<< (char *&str); - FArchive& operator<< (FName &n); - FArchive& operator<< (FString &str); - - void WriteName (const char *name); - const char *ReadName (); // The returned name disappears with the archive, unlike strings - - -inline FArchive& operator<< (SBYTE &c) { return operator<< ((BYTE &)c); } -inline FArchive& operator<< (SWORD &s) { return operator<< ((WORD &)s); } -inline FArchive& operator<< (SDWORD &i) { return operator<< ((DWORD &)i); } -inline FArchive& operator<< (SQWORD &i) { return operator<< ((QWORD &)i); } -inline FArchive& operator<< (unsigned char *&str) { return operator<< ((char *&)str); } -inline FArchive& operator<< (signed char *&str) { return operator<< ((char *&)str); } -inline FArchive& operator<< (bool &b) { return operator<< ((BYTE &)b); } - - void EnableThinkers() - { - m_ThinkersAllowed = true; - } - - bool ThinkersAllowed() - { - return m_ThinkersAllowed; - } - -protected: - enum { EObjectHashSize = 137 }; - - DWORD WriteClass (PClass *info); - PClass *ReadClass (); - PClass *ReadClass (const PClass *wanttype); - PClass *ReadStoredClass (const PClass *wanttype); - DWORD AddName (const char *name); - DWORD AddName (unsigned int start); // Name has already been added to storage - DWORD FindName (const char *name) const; - DWORD FindName (const char *name, unsigned int bucket) const; - - bool m_Persistent; // meant for persistent storage (disk)? - bool m_Loading; // extracting objects? - bool m_Storing; // inserting objects? - bool m_HubTravel; // travelling inside a hub? - FFile *m_File; // unerlying file object - - TMap ClassToArchive; // Maps PClass to archive type index - TArray ArchiveToClass; // Maps archive type index to PClass - - TMap ObjectToArchive; // Maps objects to archive index - TArray ArchiveToObject; // Maps archive index to objects - - struct NameMap - { - DWORD StringStart; // index into m_NameStorage - DWORD HashNext; // next in hash bucket - enum { NO_INDEX = 0xffffffff }; - }; - TArray m_Names; - TArray m_NameStorage; - unsigned int m_NameHash[EObjectHashSize]; - - int *m_SpriteMap; - size_t m_NumSprites; - bool m_ThinkersAllowed = false; - - FArchive (); - void AttachToFile (FFile &file); - -private: - FArchive (const FArchive &) {} - void operator= (const FArchive &) {} -}; - -// Create an FPNGChunkFile and FArchive in one step -class FPNGChunkArchive : public FArchive -{ -public: - FPNGChunkArchive (FILE *file, DWORD chunkid); - FPNGChunkArchive (FILE *file, DWORD chunkid, size_t chunklen); - ~FPNGChunkArchive (); - FPNGChunkFile Chunk; -}; - - -#endif //__FARCHIVE_H__ diff --git a/src/g_game.cpp b/src/g_game.cpp index 6eeb40219..f646b2bd1 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -78,7 +78,6 @@ #include "p_acs.h" #include "p_effect.h" #include "m_joy.h" -#include "farchive.h" #include "r_renderer.h" #include "r_utility.h" #include "a_morph.h" diff --git a/src/g_hexen/a_hexenmisc.cpp b/src/g_hexen/a_hexenmisc.cpp index 122129ede..31a17c3a3 100644 --- a/src/g_hexen/a_hexenmisc.cpp +++ b/src/g_hexen/a_hexenmisc.cpp @@ -17,7 +17,6 @@ #include "p_terrain.h" #include "m_bbox.h" #include "ravenshared.h" -#include "farchive.h" #include "v_palette.h" #include "g_game.h" #include "p_blockmap.h" diff --git a/src/g_level.cpp b/src/g_level.cpp index 76b67a9bb..b5b0b6972 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -81,7 +81,6 @@ #include "a_sharedglobal.h" #include "a_strifeglobal.h" #include "r_data/colormaps.h" -#include "farchive.h" #include "r_renderer.h" #include "r_utility.h" #include "p_spec.h" diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 8f0e2da13..bc0470474 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -45,7 +45,6 @@ #include "i_system.h" #include "gi.h" #include "gstrings.h" -#include "farchive.h" #include "p_acs.h" #include "doomstat.h" #include "d_player.h" diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp index 909b317e7..9f58ce4c3 100644 --- a/src/g_raven/a_minotaur.cpp +++ b/src/g_raven/a_minotaur.cpp @@ -11,7 +11,6 @@ #include "thingdef/thingdef.h" #include "g_level.h" #include "doomstat.h" -#include "farchive.h" #include "a_pickups.h" #include "d_player.h" #include "serializer.h" diff --git a/src/g_shared/a_armor.cpp b/src/g_shared/a_armor.cpp index e05b564f3..50472e51d 100644 --- a/src/g_shared/a_armor.cpp +++ b/src/g_shared/a_armor.cpp @@ -6,7 +6,6 @@ #include "templates.h" #include "g_level.h" #include "d_player.h" -#include "farchive.h" #include "serializer.h" diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 1ce531eea..e80e54818 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -18,7 +18,6 @@ #include "g_level.h" #include "g_game.h" #include "doomstat.h" -#include "farchive.h" #include "d_player.h" #include "p_spec.h" #include "serializer.h" diff --git a/src/g_shared/a_puzzleitems.cpp b/src/g_shared/a_puzzleitems.cpp index 512d83b49..233066edc 100644 --- a/src/g_shared/a_puzzleitems.cpp +++ b/src/g_shared/a_puzzleitems.cpp @@ -7,7 +7,6 @@ #include "c_console.h" #include "doomstat.h" #include "v_font.h" -#include "farchive.h" IMPLEMENT_CLASS(PClassPuzzleItem) diff --git a/src/g_shared/a_skies.cpp b/src/g_shared/a_skies.cpp index 1da7cd712..72091e098 100644 --- a/src/g_shared/a_skies.cpp +++ b/src/g_shared/a_skies.cpp @@ -36,8 +36,8 @@ #include "a_sharedglobal.h" #include "p_local.h" #include "p_lnspec.h" -#include "farchive.h" #include "r_sky.h" +#include "r_state.h" #include "portal.h" // arg0 = Visibility*4 for this skybox diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index eb73b22f2..023d16ec6 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -17,7 +17,6 @@ #include "doomstat.h" #include "g_level.h" #include "d_net.h" -#include "farchive.h" #include "serializer.h" #define BONUSADD 6 diff --git a/src/m_random.cpp b/src/m_random.cpp index ec6200a7d..11075916e 100644 --- a/src/m_random.cpp +++ b/src/m_random.cpp @@ -330,7 +330,7 @@ void FRandom::StaticReadRNGState(FSerializer &arc) { FRandom *rng; - arc("rngseed", rng); + arc("rngseed", rngseed); if (arc.BeginArray("rngs")) { int count = arc.ArraySize(); diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 59373237f..cb82d86e8 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -74,7 +74,6 @@ #include "p_setup.h" #include "po_man.h" #include "actorptrselect.h" -#include "farchive.h" #include "serializer.h" #include "decallib.h" #include "p_terrain.h" @@ -726,7 +725,7 @@ void ACSStringPool::ReadStrings(FSerializer &file, const char *key) { Clear(); - int32_t i, j, poolsize; + int poolsize; file("poolsize", poolsize); Pool.Resize(poolsize); @@ -737,22 +736,22 @@ void ACSStringPool::ReadStrings(FSerializer &file, const char *key) } if (file.BeginArray("pool")) { - j = file.ArraySize(); + int j = file.ArraySize(); for (int i = 0; i < j; i++) { if (file.BeginObject(nullptr)) { - i = -1; - file("index", i); - if (i >= 0 && i < Pool.Size()) + unsigned ii = UINT_MAX; + file("index", ii); + if (ii < Pool.Size()) { - file("string", Pool[i].Str) - ("lockcount", Pool[i].LockCount); + file("string", Pool[ii].Str) + ("lockcount", Pool[ii].LockCount); - unsigned h = SuperFastHash(Pool[i].Str, Pool[i].Str.Len()); + unsigned h = SuperFastHash(Pool[ii].Str, Pool[ii].Str.Len()); unsigned bucketnum = h % NUM_BUCKETS; - Pool[i].Hash = h; - Pool[i].Next = PoolBuckets[bucketnum]; + Pool[ii].Hash = h; + Pool[ii].Next = PoolBuckets[bucketnum]; PoolBuckets[bucketnum] = i; } file.EndObject(); @@ -980,7 +979,7 @@ static void WriteVars (FSerializer &file, SDWORD *vars, size_t count, const char static void ReadVars (FSerializer &arc, SDWORD *vars, size_t count, const char *key) { memset(&vars[0], 0, count * 4); - arc.Array(key, vars, count); + arc.Array(key, vars, (int)count); } //============================================================================ @@ -1038,7 +1037,7 @@ static void WriteArrayVars (FSerializer &file, FWorldGlobalArray *vars, unsigned static void ReadArrayVars (FSerializer &file, FWorldGlobalArray *vars, size_t count, const char *key) { - for (i = 0; i < count; ++i) + for (size_t i = 0; i < count; ++i) { vars[i].Clear(); } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 70fff197a..f6139f843 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -64,7 +64,6 @@ #include "v_palette.h" #include "p_enemy.h" #include "gstrings.h" -#include "farchive.h" #include "r_data/colormaps.h" #include "r_renderer.h" #include "po_man.h" diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 93b4506e3..a40208ccd 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -27,7 +27,6 @@ #include "templates.h" #include "thingdef/thingdef.h" #include "g_level.h" -#include "farchive.h" #include "d_player.h" #include "serializer.h" diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 1b9f1a057..0fe896ec6 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -52,7 +52,6 @@ #include "po_man.h" #include "p_setup.h" #include "r_data/colormaps.h" -#include "farchive.h" #include "p_lnspec.h" #include "p_acs.h" #include "p_terrain.h" diff --git a/src/p_states.cpp b/src/p_states.cpp index a56229e05..1a8116e53 100644 --- a/src/p_states.cpp +++ b/src/p_states.cpp @@ -34,7 +34,6 @@ ** */ #include "actor.h" -#include "farchive.h" #include "templates.h" #include "cmdlib.h" #include "i_system.h" diff --git a/src/p_user.cpp b/src/p_user.cpp index 3c3cdf135..0f3b6a516 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -52,7 +52,6 @@ #include "g_level.h" #include "d_net.h" #include "gstrings.h" -#include "farchive.h" #include "serializer.h" #include "r_renderer.h" #include "d_player.h" diff --git a/src/portal.cpp b/src/portal.cpp index 90cff83db..cef79820f 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -45,7 +45,6 @@ #include "c_cvars.h" #include "m_bbox.h" #include "p_tags.h" -#include "farchive.h" #include "v_text.h" #include "a_sharedglobal.h" #include "i_system.h" diff --git a/src/r_data/renderstyle.cpp b/src/r_data/renderstyle.cpp index f84c941d9..6e656f715 100644 --- a/src/r_data/renderstyle.cpp +++ b/src/r_data/renderstyle.cpp @@ -32,7 +32,6 @@ ** */ -#include "farchive.h" #include "templates.h" #include "renderstyle.h" #include "c_cvars.h" diff --git a/src/r_data/renderstyle.h b/src/r_data/renderstyle.h index 78687cec0..501c14c5f 100644 --- a/src/r_data/renderstyle.h +++ b/src/r_data/renderstyle.h @@ -34,6 +34,7 @@ **--------------------------------------------------------------------------- ** */ +#include // also #defines OPAQUE #ifdef OPAQUE @@ -130,15 +131,15 @@ union FRenderStyle { struct { - BYTE BlendOp; // Of ERenderOp type - BYTE SrcAlpha; // Of ERenderAlpha type - BYTE DestAlpha; // Of ERenderAlpha type - BYTE Flags; + uint8_t BlendOp; // Of ERenderOp type + uint8_t SrcAlpha; // Of ERenderAlpha type + uint8_t DestAlpha; // Of ERenderAlpha type + uint8_t Flags; }; - uint32 AsDWORD; + uint32_t AsDWORD; inline FRenderStyle &operator= (ERenderStyle legacy); - operator uint32() const { return AsDWORD; } + operator uint32_t() const { return AsDWORD; } bool operator==(const FRenderStyle &o) const { return AsDWORD == o.AsDWORD; } void CheckFuzz(); bool IsVisible(double alpha) const throw(); diff --git a/src/r_main.cpp b/src/r_main.cpp index 040b57b71..1e0de7ecc 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -57,7 +57,6 @@ #include "st_start.h" #include "v_font.h" #include "r_data/colormaps.h" -#include "farchive.h" #include "p_maputl.h" // MACROS ------------------------------------------------------------------ diff --git a/src/textures/anim_switches.cpp b/src/textures/anim_switches.cpp index 9a2aa2441..14fb4db84 100644 --- a/src/textures/anim_switches.cpp +++ b/src/textures/anim_switches.cpp @@ -43,7 +43,6 @@ #include "cmdlib.h" #include "sc_man.h" #include "gi.h" -#include "farchive.h" static int SortSwitchDefs (const void *a, const void *b) diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index a2b1c1319..74f9b1f55 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -43,7 +43,6 @@ #include "templates.h" #include "w_wad.h" #include "g_level.h" -#include "farchive.h" #include "serializer.h" // MACROS ------------------------------------------------------------------ diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 9c7e98d08..3fb01dc6c 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -40,6 +40,7 @@ #include "templates.h" #include "i_system.h" #include "r_data/r_translate.h" +#include "r_data/sprites.h" #include "c_dispatch.h" #include "v_text.h" #include "sc_man.h" @@ -48,7 +49,6 @@ #include "cmdlib.h" #include "g_level.h" #include "m_fixed.h" -#include "farchive.h" #include "v_video.h" #include "r_renderer.h" #include "r_sky.h" diff --git a/src/v_blend.cpp b/src/v_blend.cpp index b8f3e713d..e1552105f 100644 --- a/src/v_blend.cpp +++ b/src/v_blend.cpp @@ -51,7 +51,6 @@ #include "colormatcher.h" #include "v_palette.h" #include "d_player.h" -#include "farchive.h" diff --git a/src/v_font.cpp b/src/v_font.cpp index dd2bf7068..0eb28a67c 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -90,7 +90,6 @@ The FON2 header is followed by variable length data: #include "cmdlib.h" #include "sc_man.h" #include "hu_stuff.h" -#include "farchive.h" #include "textures/textures.h" #include "r_data/r_translate.h" #include "colormatcher.h"