mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 00:21:43 +00:00
- Rewrote FName to use only POD types for its static data so that it can be used
without any explicit constructors being called. - Fixed: ZTwinedTorchUnlit, ZWallTorchUnlit, ZFireBullUnlit, and ZCauldronUnlit were missing game filters. SVN r79 (trunk)
This commit is contained in:
parent
d06793ad7e
commit
e78385f807
5 changed files with 264 additions and 81 deletions
|
@ -464,7 +464,7 @@ DObject::DObject ()
|
|||
: ObjectFlags(0), Class(0)
|
||||
{
|
||||
if (FreeIndices.Pop (Index))
|
||||
Objects[Index] = this;
|
||||
Objects[(unsigned int)Index] = this;
|
||||
else
|
||||
Index = Objects.Push (this);
|
||||
}
|
||||
|
@ -473,7 +473,7 @@ DObject::DObject (TypeInfo *inClass)
|
|||
: ObjectFlags(0), Class(inClass)
|
||||
{
|
||||
if (FreeIndices.Pop (Index))
|
||||
Objects[Index] = this;
|
||||
Objects[(unsigned int)Index] = this;
|
||||
else
|
||||
Index = Objects.Push (this);
|
||||
}
|
||||
|
@ -559,7 +559,7 @@ void DObject::RemoveFromArray ()
|
|||
}
|
||||
else if (Objects.Size() > Index)
|
||||
{
|
||||
Objects[Index] = NULL;
|
||||
Objects[(unsigned int)Index] = NULL;
|
||||
FreeIndices.Push (Index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -551,7 +551,7 @@ 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 = 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);
|
||||
|
|
220
src/name.cpp
220
src/name.cpp
|
@ -1,6 +1,71 @@
|
|||
/*
|
||||
** name.cpp
|
||||
** Implements int-as-string mapping.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2005-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.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "name.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "m_alloc.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// The number of bytes to allocate to each NameBlock unless somebody is evil
|
||||
// and wants a really long name. In that case, it gets its own NameBlock
|
||||
// that is just large enough to hold it.
|
||||
#define BLOCK_SIZE 1024
|
||||
|
||||
// How many entries to grow the NameArray by when it needs to grow.
|
||||
#define NAME_GROW_AMOUNT 48
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// Name text is stored in a linked list of NameBlock structures. This
|
||||
// is really the header for the block, with the remainder of the block
|
||||
// being populated by text for names.
|
||||
|
||||
struct FName::NameManager::NameBlock
|
||||
{
|
||||
size_t NextAlloc;
|
||||
NameBlock *NextBlock;
|
||||
};
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
FName::NameManager FName::NameData;
|
||||
|
||||
// Define the predefined names.
|
||||
static const char *PredefinedNames[] =
|
||||
|
@ -10,31 +75,38 @@ static const char *PredefinedNames[] =
|
|||
#undef xx
|
||||
};
|
||||
|
||||
int FName::Buckets[FName::HASH_SIZE];
|
||||
TArray<FName::MainName> FName::NameArray;
|
||||
bool FName::Inited;
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
FName::MainName::MainName (int next)
|
||||
: NextHash(next)
|
||||
{
|
||||
}
|
||||
//==========================================================================
|
||||
//
|
||||
// FName :: NameManager :: FindName
|
||||
//
|
||||
// Returns the index of a name. If the name does not exist and noCreate is
|
||||
// true, then it returns false. If the name does not exist and noCreate is
|
||||
// false, then the name is added to the table and its new index is returned.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FName::FindName (const char *text, bool noCreate)
|
||||
int FName::NameManager::FindName (const char *text, bool noCreate)
|
||||
{
|
||||
if (!Inited) InitBuckets ();
|
||||
if (!Inited)
|
||||
{
|
||||
InitBuckets ();
|
||||
}
|
||||
|
||||
if (text == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hash = MakeKey (text) % HASH_SIZE;
|
||||
int scanner = Buckets[hash];
|
||||
DWORD hash = MakeKey (text);
|
||||
DWORD bucket = hash % HASH_SIZE;
|
||||
int scanner = Buckets[bucket];
|
||||
|
||||
// See if the name already exists.
|
||||
while (scanner >= 0)
|
||||
{
|
||||
if (stricmp (NameArray[scanner].Text.GetChars(), text) == 0)
|
||||
if (NameArray[scanner].Hash == hash && stricmp (NameArray[scanner].Text, text) == 0)
|
||||
{
|
||||
return scanner;
|
||||
}
|
||||
|
@ -47,28 +119,122 @@ int FName::FindName (const char *text, bool noCreate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Assigning the string to the name after pushing it avoids needless
|
||||
// manipulation of the string pool.
|
||||
MainName entry (Buckets[hash]);
|
||||
unsigned int index = NameArray.Push (entry);
|
||||
NameArray[index].Text = text;
|
||||
Buckets[hash] = index;
|
||||
return index;
|
||||
return AddName (text, hash, bucket);
|
||||
}
|
||||
|
||||
void FName::InitBuckets ()
|
||||
{
|
||||
size_t i;
|
||||
//==========================================================================
|
||||
//
|
||||
// FName :: NameManager :: InitBuckets
|
||||
//
|
||||
// Sets up the hash table and inserts all the default names into the table.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FName::NameManager::InitBuckets ()
|
||||
{
|
||||
Inited = true;
|
||||
for (i = 0; i < HASH_SIZE; ++i)
|
||||
{
|
||||
Buckets[i] = -1;
|
||||
}
|
||||
memset (Buckets, -1, sizeof(Buckets));
|
||||
|
||||
// Register built-in names. 'None' must be name 0.
|
||||
for (i = 0; i < countof(PredefinedNames); ++i)
|
||||
for (size_t i = 0; i < countof(PredefinedNames); ++i)
|
||||
{
|
||||
FindName (PredefinedNames[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FName :: NameManager :: AddName
|
||||
//
|
||||
// Adds a new name to the name table.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FName::NameManager::AddName (const char *text, DWORD hash, DWORD bucket)
|
||||
{
|
||||
char *textstore;
|
||||
NameBlock *block = Blocks;
|
||||
size_t len = strlen (text) + 1;
|
||||
|
||||
// Get a block large enough for the name. Only the first block in the
|
||||
// list is ever considered for name storage.
|
||||
if (block == NULL || block->NextAlloc + len >= BLOCK_SIZE)
|
||||
{
|
||||
block = AddBlock (len);
|
||||
}
|
||||
|
||||
// Copy the string into the block.
|
||||
textstore = (char *)block + block->NextAlloc;
|
||||
strcpy (textstore, text);
|
||||
block->NextAlloc += len;
|
||||
|
||||
// Add an entry for the name to the NameArray
|
||||
if (NumNames >= MaxNames)
|
||||
{
|
||||
// If no names have been defined yet, make the first allocation
|
||||
// large enough to hold all the predefined names.
|
||||
MaxNames += MaxNames == 0 ? countof(PredefinedNames) + NAME_GROW_AMOUNT : NAME_GROW_AMOUNT;
|
||||
|
||||
NameArray = (NameEntry *)M_Realloc (NameArray, MaxNames * sizeof(NameEntry));
|
||||
}
|
||||
|
||||
NameArray[NumNames].Text = textstore;
|
||||
NameArray[NumNames].Hash = hash;
|
||||
NameArray[NumNames].NextHash = Buckets[bucket];
|
||||
Buckets[bucket] = NumNames;
|
||||
|
||||
return NumNames++;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FName :: NameManager :: AddBlock
|
||||
//
|
||||
// Creates a new NameBlock at least large enough to hold the required
|
||||
// number of chars.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FName::NameManager::NameBlock *FName::NameManager::AddBlock (size_t len)
|
||||
{
|
||||
NameBlock *block;
|
||||
|
||||
len += sizeof(NameBlock);
|
||||
if (len < BLOCK_SIZE)
|
||||
{
|
||||
len = BLOCK_SIZE;
|
||||
}
|
||||
block = (NameBlock *)M_Malloc (len);
|
||||
block->NextAlloc = sizeof(NameBlock);
|
||||
block->NextBlock = Blocks;
|
||||
Blocks = block;
|
||||
return block;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FName :: NameManager :: ~NameManager
|
||||
//
|
||||
// Release all the memory used for name bookkeeping.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FName::NameManager::~NameManager()
|
||||
{
|
||||
NameBlock *block, *next;
|
||||
|
||||
for (block = Blocks; block != NULL; block = next)
|
||||
{
|
||||
next = block->NextBlock;
|
||||
free (block);
|
||||
}
|
||||
Blocks = NULL;
|
||||
|
||||
if (NameArray != NULL)
|
||||
{
|
||||
free (NameArray);
|
||||
NameArray = NULL;
|
||||
}
|
||||
NumNames = MaxNames = 0;
|
||||
memset (Buckets, -1, sizeof(Buckets));
|
||||
}
|
||||
|
|
115
src/name.h
115
src/name.h
|
@ -1,8 +1,40 @@
|
|||
/*
|
||||
** name.h
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2005-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 NAME_H
|
||||
#define NAME_H
|
||||
|
||||
#include "zstring.h"
|
||||
#include "tarray.h"
|
||||
#include "doomtype.h"
|
||||
|
||||
enum ENamedName
|
||||
{
|
||||
|
@ -15,28 +47,24 @@ class FName
|
|||
{
|
||||
public:
|
||||
FName () : Index(0) {}
|
||||
FName (const char *text) { Index = FindName (text, false); }
|
||||
FName (const FString &text) { Index = FindName (text.GetChars(), false); }
|
||||
FName (const char *text, bool noCreate) { Index = FindName (text, noCreate); }
|
||||
FName (const FString &text, bool noCreate) { Index = FindName (text.GetChars(), noCreate); }
|
||||
FName (const char *text) { Index = NameData.FindName (text, false); }
|
||||
FName (const char *text, bool noCreate) { Index = NameData.FindName (text, noCreate); }
|
||||
FName (const FName &other) { Index = other.Index; }
|
||||
FName (ENamedName index) { Index = index; }
|
||||
// ~FName () {} // Names can be added but never removed.
|
||||
|
||||
int GetIndex() const { return Index; }
|
||||
operator int() const { return Index; }
|
||||
const FString &GetText() const { return NameArray[Index].Text; }
|
||||
const char *GetChars() const { return NameArray[Index].Text.GetChars(); }
|
||||
const char *GetChars() const { return NameData.NameArray[Index].Text; }
|
||||
operator const char *() const { return NameData.NameArray[Index].Text; }
|
||||
|
||||
FName &operator = (const char *text) { Index = FindName (text, false); return *this; }
|
||||
FName &operator = (const FString &text) { Index = FindName (text.GetChars(), false); return *this; }
|
||||
FName &operator = (const char *text) { Index = NameData.FindName (text, false); return *this; }
|
||||
FName &operator = (const FName &other) { Index = other.Index; return *this; }
|
||||
FName &operator = (ENamedName index) { Index = index; return *this; }
|
||||
|
||||
int SetName (const char *text, bool noCreate) { return Index = FindName (text, false); }
|
||||
int SetName (const FString &text, bool noCreate) { return Index = FindName (text.GetChars(), false); }
|
||||
int SetName (const char *text, bool noCreate=false) { return Index = NameData.FindName (text, noCreate); }
|
||||
|
||||
bool IsValidName() const { return (unsigned int)Index < NameArray.Size(); }
|
||||
bool IsValidName() const { return (unsigned)Index < (unsigned)NameData.NumNames; }
|
||||
|
||||
// Note that the comparison operators compare the names' indices, not
|
||||
// their text, so they cannot be used to do a lexicographical sort.
|
||||
|
@ -57,47 +85,36 @@ public:
|
|||
private:
|
||||
int Index;
|
||||
|
||||
enum { HASH_SIZE = 256 };
|
||||
|
||||
struct MainName
|
||||
struct NameEntry
|
||||
{
|
||||
MainName (int next);
|
||||
MainName (const MainName &other) : Text(other.Text), NextHash(other.NextHash) {}
|
||||
MainName () {}
|
||||
FString Text;
|
||||
char *Text;
|
||||
DWORD Hash;
|
||||
int NextHash;
|
||||
|
||||
void *operator new (size_t size, MainName *addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
void operator delete (void *, MainName *)
|
||||
{
|
||||
}
|
||||
};
|
||||
static TArray<MainName> NameArray;
|
||||
static int Buckets[HASH_SIZE];
|
||||
static int FindName (const char *text, bool noCreate);
|
||||
static void InitBuckets ();
|
||||
static bool Inited;
|
||||
|
||||
#ifndef __GNUC__
|
||||
template<> friend void CopyForTArray<MainName> (MainName &dst, MainName &src)
|
||||
struct NameManager
|
||||
{
|
||||
dst.NextHash = src.NextHash;
|
||||
CopyForTArray (dst.Text, src.Text);
|
||||
}
|
||||
#else
|
||||
template<class MainName> friend inline void CopyForTArray (MainName &dst, MainName &src);
|
||||
#endif
|
||||
// No constructor because we can't ensure that it actually gets
|
||||
// called before any FNames are constructed during startup. This
|
||||
// means this struct must only exist in the program's BSS section.
|
||||
~NameManager();
|
||||
|
||||
enum { HASH_SIZE = 256 };
|
||||
struct NameBlock;
|
||||
|
||||
NameBlock *Blocks;
|
||||
NameEntry *NameArray;
|
||||
int NumNames, MaxNames;
|
||||
int Buckets[HASH_SIZE];
|
||||
|
||||
int FindName (const char *text, bool noCreate);
|
||||
int AddName (const char *text, DWORD hash, DWORD bucket);
|
||||
NameBlock *AddBlock (size_t len);
|
||||
void InitBuckets ();
|
||||
bool Inited;
|
||||
};
|
||||
|
||||
static NameManager NameData;
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
template<> inline void CopyForTArray<FName::MainName> (FName::MainName &dst, FName::MainName &src)
|
||||
{
|
||||
dst.NextHash = src.NextHash;
|
||||
CopyForTArray (dst.Text, src.Text);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1082,7 +1082,7 @@ void FFontChar2::MakeTexture ()
|
|||
I_FatalError ("The font %s is corrupt", name);
|
||||
}
|
||||
|
||||
if (Spans!=NULL) Spans = CreateSpans (Pixels);
|
||||
Spans = CreateSpans (Pixels);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
Loading…
Reference in a new issue