diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 766bdbc08..f03854489 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -733,6 +733,7 @@ set (PCH_SOURCES core/utility/sc_man.cpp core/utility/stringtable.cpp core/utility/stats.cpp + core/utility/palette.cpp core/filesystem/filesystem.cpp core/filesystem/ancientzip.cpp diff --git a/source/core/filesystem/filesystem.cpp b/source/core/filesystem/filesystem.cpp index 5d31560ed..cd5c50a56 100644 --- a/source/core/filesystem/filesystem.cpp +++ b/source/core/filesystem/filesystem.cpp @@ -49,6 +49,7 @@ #include "resourcefile.h" #include "v_text.h" #include "c_dispatch.h" +#include "zstring.h" //#include "md5.h" //#include "doomstat.h" diff --git a/source/core/menu/imagescroller.cpp b/source/core/menu/imagescroller.cpp index 7f88e7be4..0ee93cca6 100644 --- a/source/core/menu/imagescroller.cpp +++ b/source/core/menu/imagescroller.cpp @@ -42,6 +42,7 @@ #include "baselayer.h" #include "gamecontrol.h" #include "build.h" +#include "zstring.h" //============================================================================= // diff --git a/source/core/menu/menudef.cpp b/source/core/menu/menudef.cpp index c3276d7d6..ea5de38c7 100644 --- a/source/core/menu/menudef.cpp +++ b/source/core/menu/menudef.cpp @@ -47,6 +47,7 @@ #include "c_cvars.h" #include "optionmenuitems.h" #include "i_soundfont.h" +#include "zstring.h" #include // Menu-relevant content that gets filled in by scripts. This will get processed after the game has loaded. diff --git a/source/core/rendering/hwrenderer/postprocessing/hw_postprocess.cpp b/source/core/rendering/hwrenderer/postprocessing/hw_postprocess.cpp index a1e566a7e..c8ad01257 100644 --- a/source/core/rendering/hwrenderer/postprocessing/hw_postprocess.cpp +++ b/source/core/rendering/hwrenderer/postprocessing/hw_postprocess.cpp @@ -26,6 +26,7 @@ #include "imagehelpers.h" #include "hwrenderer/utility/hw_cvars.h" #include "hwrenderer/postprocessing/hw_postprocess_cvars.h" +#include "palutil.h" #include Postprocess hw_postprocess; diff --git a/source/core/utility/memarena.cpp b/source/core/utility/memarena.cpp index d769bebaf..f576d49fa 100644 --- a/source/core/utility/memarena.cpp +++ b/source/core/utility/memarena.cpp @@ -41,6 +41,7 @@ #include "memarena.h" #include "printf.h" #include "cmdlib.h" +#include "m_alloc.h" struct FMemArena::Block { @@ -201,7 +202,7 @@ void FMemArena::FreeBlockChain(Block *&top) for (Block *next, *block = top; block != NULL; block = next) { next = block->NextBlock; - free(block); + M_Free(block); } top = NULL; } @@ -241,7 +242,7 @@ FMemArena::Block *FMemArena::AddBlock(size_t size) // other things. size += BlockSize/2; } - mem = (Block *)malloc(size); + mem = (Block *)M_Malloc(size); mem->Limit = (uint8_t *)mem + size; } mem->Reset(); diff --git a/source/core/utility/name.cpp b/source/core/utility/name.cpp index c548111a7..a34575df7 100644 --- a/source/core/utility/name.cpp +++ b/source/core/utility/name.cpp @@ -36,6 +36,7 @@ #include "name.h" #include "superfasthash.h" #include "cmdlib.h" +#include "m_alloc.h" // MACROS ------------------------------------------------------------------ @@ -221,7 +222,7 @@ int FName::NameManager::AddName (const char *text, unsigned int hash, unsigned i // large enough to hold all the predefined names. MaxNames += MaxNames == 0 ? countof(PredefinedNames) + NAME_GROW_AMOUNT : NAME_GROW_AMOUNT; - NameArray = (NameEntry *)realloc (NameArray, MaxNames * sizeof(NameEntry)); + NameArray = (NameEntry *)M_Realloc (NameArray, MaxNames * sizeof(NameEntry)); } NameArray[NumNames].Text = textstore; @@ -250,7 +251,7 @@ FName::NameManager::NameBlock *FName::NameManager::AddBlock (size_t len) { len = BLOCK_SIZE; } - block = (NameBlock *)malloc (len); + block = (NameBlock *)M_Malloc (len); block->NextAlloc = sizeof(NameBlock); block->NextBlock = Blocks; Blocks = block; @@ -274,13 +275,13 @@ FName::NameManager::~NameManager() for (block = Blocks; block != NULL; block = next) { next = block->NextBlock; - free (block); + M_Free (block); } Blocks = NULL; if (NameArray != NULL) { - free (NameArray); + M_Free (NameArray); NameArray = NULL; } NumNames = MaxNames = 0; diff --git a/source/core/utility/name.h b/source/core/utility/name.h index 9e547a4b8..ecc9c36bf 100644 --- a/source/core/utility/name.h +++ b/source/core/utility/name.h @@ -52,6 +52,8 @@ public: FName (const char *text) { Index = NameData.FindName (text, false); } FName (const char *text, bool noCreate) { Index = NameData.FindName (text, noCreate); } FName (const char *text, size_t textlen, bool noCreate) { Index = NameData.FindName (text, textlen, noCreate); } + FName (const FString &text); + FName (const FString &text, bool noCreate); FName (const FName &other) = default; FName (ENamedName index) { Index = index; } // ~FName () {} // Names can be added but never removed. @@ -62,6 +64,7 @@ public: operator const char *() const { return NameData.NameArray[Index].Text; } FName &operator = (const char *text) { Index = NameData.FindName (text, false); return *this; } + FName &operator = (const FString &text); FName &operator = (const FName &other) = default; FName &operator = (ENamedName index) { Index = index; return *this; } diff --git a/source/core/utility/palentry.h b/source/core/utility/palentry.h index 813ed0f2b..4064f4ac7 100644 --- a/source/core/utility/palentry.h +++ b/source/core/utility/palentry.h @@ -3,6 +3,7 @@ #include #include +// Beware of windows.h :( #ifdef max #undef min #undef max diff --git a/source/core/utility/printf.h b/source/core/utility/printf.h index 8d42b9bc1..70681004c 100644 --- a/source/core/utility/printf.h +++ b/source/core/utility/printf.h @@ -22,8 +22,9 @@ enum PRINT_LOG, // only to logfile PRINT_BOLD = 200, // What Printf_Bold used PRINT_TYPES = 1023, // Bitmask. - PRINT_NOTIFY = 1024, // Flag - add to notify buffer + PRINT_NONOTIFY = 1024, // Flag - do not add to notify buffer PRINT_NOLOG = 2048, // Flag - do not print to log file + PRINT_NOTIFY = 4096, // Flag - add to notify buffer }; enum diff --git a/source/core/utility/sc_man.cpp b/source/core/utility/sc_man.cpp index a02cd09a9..bbb73f10d 100644 --- a/source/core/utility/sc_man.cpp +++ b/source/core/utility/sc_man.cpp @@ -46,6 +46,7 @@ #include "name.h" #include "v_text.h" #include "templates.h" +#include "zstring.h" #include "filesystem/filesystem.h" // MACROS ------------------------------------------------------------------ @@ -557,11 +558,7 @@ bool FScanner::GetToken () { if (ScanString (true)) { - if (TokenType == TK_NameConst) - { - Name = FName(String); - } - else if (TokenType == TK_IntConst) + if (TokenType == TK_IntConst) { char *stopper; // Check for unsigned @@ -570,13 +567,13 @@ bool FScanner::GetToken () { TokenType = TK_UIntConst; BigNumber = (int64_t)strtoull(String, &stopper, 0); - Number = (int)clamp(BigNumber, 0, UINT_MAX); + Number = (int)BigNumber;// clamp(BigNumber, 0, UINT_MAX); Float = (unsigned)Number; } else { BigNumber = strtoll(String, &stopper, 0); - Number = (int)clamp(BigNumber, INT_MIN, INT_MAX); + Number = (int)BigNumber;// clamp(BigNumber, 0, UINT_MAX); Float = Number; } } @@ -678,7 +675,7 @@ bool FScanner::GetNumber () else { BigNumber = strtoll(String, &stopper, 0); - Number = (int)clamp(BigNumber, INT_MIN, INT_MAX); + Number = (int)BigNumber;// clamp(BigNumber, 0, UINT_MAX); if (*stopper != 0) { ScriptError ("SC_GetNumber: Bad numeric constant \"%s\".", String); @@ -735,7 +732,7 @@ bool FScanner::CheckNumber () else { BigNumber = strtoll (String, &stopper, 0); - Number = (int)clamp(BigNumber, INT_MIN, INT_MAX); + Number = (int)BigNumber;// clamp(BigNumber, 0, UINT_MAX); if (*stopper != 0) { UnGet(); diff --git a/source/core/utility/sc_man.h b/source/core/utility/sc_man.h index 8dbd443d4..0ca584913 100644 --- a/source/core/utility/sc_man.h +++ b/source/core/utility/sc_man.h @@ -82,7 +82,6 @@ public: int Number; int64_t BigNumber; double Float; - FName Name; int Line; bool End; bool Crossed; diff --git a/source/core/utility/tarray.h b/source/core/utility/tarray.h index 97515f13f..7bafeb9ee 100644 --- a/source/core/utility/tarray.h +++ b/source/core/utility/tarray.h @@ -31,6 +31,20 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** +** NOTE: TArray takes advantage of the assumption that the contained type is +** able to be trivially moved. The definition of trivially movable by the C++ +** standard is more strict than the actual set of types that can be moved with +** memmove. For example, FString uses non-trivial constructors/destructor in +** order to maintain the reference count, but can be "safely" by passed if the +** opaque destructor call is avoided. Similarly types like TArray itself which +** only null the owning pointers when moving which can be skipped if the +** destructor is not called. +** +** It is possible that with LTO TArray could be made safe for non-trivial types, +** but we don't wish to rely on LTO to reach expected performance. The set of +** types which can not be contained by TArray as a result of this choice is +** actually extremely small. +** */ @@ -47,6 +61,8 @@ #include // for mingw #endif +#include "m_alloc.h" + template class TIterator : public std::iterator { public: @@ -164,7 +180,7 @@ public: { Most = (unsigned)max; Count = (unsigned)(reserve? max : 0); - Array = (T *)malloc (sizeof(T)*max); + Array = (T *)M_Malloc (sizeof(T)*max); if (reserve && Count > 0) { ConstructEmpty(0, Count - 1); @@ -190,7 +206,7 @@ public: { DoDelete (0, Count-1); } - free (Array); + M_Free (Array); } DoCopy (other); } @@ -204,7 +220,7 @@ public: { DoDelete (0, Count-1); } - free (Array); + M_Free (Array); } Array = other.Array; other.Array = NULL; Most = other.Most; other.Most = 0; @@ -219,7 +235,7 @@ public: { DoDelete (0, Count-1); } - free (Array); + M_Free (Array); Array = NULL; Count = 0; Most = 0; @@ -357,7 +373,8 @@ public: Array[index].~T(); if (index < --Count) { - memmove (&Array[index], &Array[index+1], sizeof(T)*(Count - index)); + // Cast to void to assume trivial move + memmove ((void*)&Array[index], (const void*)&Array[index+1], sizeof(T)*(Count - index)); } } } @@ -377,7 +394,8 @@ public: Count -= deletecount; if (index < Count) { - memmove (&Array[index], &Array[index+deletecount], sizeof(T)*(Count - index)); + // Cast to void to assume trivial move + memmove ((void*)&Array[index], (const void*)&Array[index+deletecount], sizeof(T)*(Count - index)); } } } @@ -399,7 +417,8 @@ public: Resize (Count + 1); // Now move items from the index and onward out of the way - memmove (&Array[index+1], &Array[index], sizeof(T)*(Count - index - 1)); + // Cast to void to assume trivial move + memmove ((void*)&Array[index+1], (const void*)&Array[index], sizeof(T)*(Count - index - 1)); // And put the new element in ::new ((void *)&Array[index]) T(item); @@ -415,7 +434,7 @@ public: { if (Array != NULL) { - free (Array); + M_Free (Array); Array = NULL; } } @@ -505,7 +524,7 @@ public: Most = 0; if (Array != nullptr) { - free(Array); + M_Free(Array); Array = nullptr; } } @@ -527,7 +546,7 @@ private: Most = Count = other.Count; if (Count != 0) { - Array = (T *)malloc (sizeof(T)*Most); + Array = (T *)M_Malloc (sizeof(T)*Most); for (unsigned int i = 0; i < Count; ++i) { ::new(&Array[i]) T(other.Array[i]); @@ -542,7 +561,7 @@ private: void DoResize () { size_t allocsize = sizeof(T)*Most; - Array = (T *)realloc (Array, allocsize); + Array = (T *)M_Realloc (Array, allocsize); } void DoDelete (unsigned int first, unsigned int last) @@ -607,6 +626,7 @@ public: typedef TIterator iterator; typedef TIterator const_iterator; + typedef T value_type; iterator begin() { @@ -1052,7 +1072,7 @@ protected: // Round size up to nearest power of 2 for (Size = 1; Size < size; Size <<= 1) { } - Nodes = (Node *)malloc(Size * sizeof(Node)); + Nodes = (Node *)M_Malloc(Size * sizeof(Node)); LastFree = &Nodes[Size]; /* all positions are free */ for (hash_t i = 0; i < Size; ++i) { @@ -1069,7 +1089,7 @@ protected: Nodes[i].~Node(); } } - free(Nodes); + M_Free(Nodes); Nodes = NULL; Size = 0; LastFree = NULL; @@ -1093,7 +1113,7 @@ protected: nold[i].~Node(); } } - free(nold); + M_Free(nold); } void Rehash() @@ -1518,6 +1538,7 @@ public: typedef TIterator iterator; typedef TIterator const_iterator; + typedef T value_type; iterator begin() { diff --git a/source/core/utility/templates.h b/source/core/utility/templates.h index 294b3ebc5..48d306cf8 100644 --- a/source/core/utility/templates.h +++ b/source/core/utility/templates.h @@ -1,7 +1,133 @@ +/* +** templates.h +** Some useful template functions +** +**--------------------------------------------------------------------------- +** 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 __TEMPLATES_H__ +#define __TEMPLATES_H__ + +#ifdef _MSC_VER #pragma once +#endif -// we do not want C++17 just for this one function... +#include +#include +#include + +//========================================================================== +// +// BinarySearch +// +// Searches an array sorted in ascending order for an element matching +// the desired key. +// +// Template parameters: +// ClassType - The class to be searched +// KeyType - The type of the key contained in the class +// +// Function parameters: +// first - Pointer to the first element in the array +// max - The number of elements in the array +// keyptr - Pointer to the key member of ClassType +// key - The key value to look for +// +// Returns: +// A pointer to the element with a matching key or NULL if none found. +//========================================================================== + +template +inline +const ClassType *BinarySearch (const ClassType *first, int max, + const KeyType ClassType::*keyptr, const KeyType key) +{ + int min = 0; + --max; + + while (min <= max) + { + int mid = (min + max) / 2; + const ClassType *probe = &first[mid]; + const KeyType &seekey = probe->*keyptr; + if (seekey == key) + { + return probe; + } + else if (seekey < key) + { + min = mid + 1; + } + else + { + max = mid - 1; + } + } + return NULL; +} + +//========================================================================== +// +// MIN +// +// Returns the minimum of a and b. +//========================================================================== + +#ifdef MIN +#undef MIN +#endif + +template +inline +const T MIN (const T a, const T b) +{ + return a < b ? a : b; +} + +//========================================================================== +// +// MAX +// +// Returns the maximum of a and b. +//========================================================================== + +#ifdef MAX +#undef MAX +#endif + +template +inline +const T MAX (const T a, const T b) +{ + return a > b ? a : b; +} //========================================================================== // @@ -16,3 +142,5 @@ T clamp (const T in, const T min, const T max) { return in <= min ? min : in >= max ? max : in; } + +#endif //__TEMPLATES_H__ diff --git a/source/core/utility/zstring.h b/source/core/utility/zstring.h index 23795d41a..4b636ac77 100644 --- a/source/core/utility/zstring.h +++ b/source/core/utility/zstring.h @@ -39,6 +39,7 @@ #include #include #include "tarray.h" +#include "name.h" #ifdef __GNUC__ #define PRINTFISH(x) __attribute__((format(printf, 2, x))) @@ -194,12 +195,14 @@ public: FString &operator += (const FString &tail); FString &operator += (const char *tail); FString &operator += (char tail); + FString &operator += (const FName &name) { return *this += name.GetChars(); } FString &AppendCStrPart (const char *tail, size_t tailLen); FString &CopyCStrPart(const char *tail, size_t tailLen); FString &operator << (const FString &tail) { return *this += tail; } FString &operator << (const char *tail) { return *this += tail; } FString &operator << (char tail) { return *this += tail; } + FString &operator << (const FName &name) { return *this += name.GetChars(); } const char &Front() const { assert(IsNotEmpty()); return Chars[0]; } const char &Back() const { assert(IsNotEmpty()); return Chars[Len() - 1]; } @@ -409,6 +412,13 @@ public: bool operator <= (const char *) const = delete; bool operator >= (const char *) const = delete; + bool operator == (FName) const = delete; + bool operator != (FName) const = delete; + bool operator < (FName) const = delete; + bool operator > (FName) const = delete; + bool operator <= (FName) const = delete; + bool operator >= (FName) const = delete; + private: }; @@ -420,6 +430,13 @@ bool operator > (const char *, const FString &) = delete; bool operator <= (const char *, const FString &) = delete; bool operator >= (const char *, const FString &) = delete; +bool operator == (FName, const FString &) = delete; +bool operator != (FName, const FString &) = delete; +bool operator < (FName, const FString &) = delete; +bool operator > (FName, const FString &) = delete; +bool operator <= (FName, const FString &) = delete; +bool operator >= (FName, const FString &) = delete; + class FStringf : public FString { public: @@ -460,6 +477,12 @@ namespace StringFormat #undef PRINTFISH +// FName inline implementations that take FString parameters + +inline FName::FName(const FString &text) { Index = NameData.FindName (text.GetChars(), text.Len(), false); } +inline FName::FName(const FString &text, bool noCreate) { Index = NameData.FindName (text.GetChars(), text.Len(), noCreate); } +inline FName &FName::operator = (const FString &text) { Index = NameData.FindName (text.GetChars(), text.Len(), false); return *this; } + // Hash FStrings on their contents. (used by TMap) #include "superfasthash.h" diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index fb7eb678b..7ef5cd761 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "imagehelpers.h" #include "compat.h" #include "duke3d.h" +#include "palutil.h" #include "gamestructures.h" #include "menus.h" #include "osdcmds.h"