diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 96f5be4ce..eb126d37a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1127,6 +1127,7 @@ set (PCH_SOURCES utility/m_random.cpp utility/memarena.cpp utility/md5.cpp + utility/superfasthash.cpp utility/nodebuilder/nodebuild.cpp utility/nodebuilder/nodebuild_classify_nosse2.cpp utility/nodebuilder/nodebuild_events.cpp diff --git a/src/console/c_dispatch.cpp b/src/console/c_dispatch.cpp index 1921e2be3..6c9d1399e 100644 --- a/src/console/c_dispatch.cpp +++ b/src/console/c_dispatch.cpp @@ -299,142 +299,6 @@ static int ListActionCommands (const char *pattern) return count; } -/* ======================================================================== */ - -/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh derivative - license. See: - http://www.azillionmonkeys.com/qed/weblicense.html for license details. - - http://www.azillionmonkeys.com/qed/hash.html */ - -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ - || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) -#define get16bits(d) (*((const uint16_t *) (d))) -#endif - -#if !defined (get16bits) -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ - +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif - -uint32_t SuperFastHash (const char *data, size_t len) -{ - uint32_t hash = 0, tmp; - size_t rem; - - if (len == 0 || data == NULL) return 0; - - rem = len & 3; - len >>= 2; - - /* Main loop */ - for (;len > 0; len--) - { - hash += get16bits (data); - tmp = (get16bits (data+2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - data += 2*sizeof (uint16_t); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) - { - case 3: hash += get16bits (data); - hash ^= hash << 16; - hash ^= data[sizeof (uint16_t)] << 18; - hash += hash >> 11; - break; - case 2: hash += get16bits (data); - hash ^= hash << 11; - hash += hash >> 17; - break; - case 1: hash += *data; - hash ^= hash << 10; - hash += hash >> 1; - } - - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - - return hash; -} - -/* A modified version to do a case-insensitive hash */ - -#undef get16bits -#define get16bits(d) ((((uint32_t)tolower(((const uint8_t *)(d))[1])) << 8)\ - +(uint32_t)tolower(((const uint8_t *)(d))[0]) ) - -uint32_t SuperFastHashI (const char *data, size_t len) -{ - uint32_t hash = 0, tmp; - size_t rem; - - if (len <= 0 || data == NULL) return 0; - - rem = len & 3; - len >>= 2; - - /* Main loop */ - for (;len > 0; len--) - { - hash += get16bits (data); - tmp = (get16bits (data+2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - data += 2*sizeof (uint16_t); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) - { - case 3: hash += get16bits (data); - hash ^= hash << 16; - hash ^= tolower(data[sizeof (uint16_t)]) << 18; - hash += hash >> 11; - break; - case 2: hash += get16bits (data); - hash ^= hash << 11; - hash += hash >> 17; - break; - case 1: hash += tolower(*data); - hash ^= hash << 10; - hash += hash >> 1; - } - - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - - return hash; -} - -/* ======================================================================== */ - -unsigned int MakeKey (const char *s) -{ - if (s == NULL) - { - return 0; - } - return SuperFastHashI (s, strlen (s)); -} - -unsigned int MakeKey (const char *s, size_t len) -{ - return SuperFastHashI (s, len); -} // FindButton scans through the actionbits[] array // for a matching key and returns an index or -1 if diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index 104895ed0..0d3909b0f 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -240,7 +240,7 @@ class SBarInfoCommandFlowControl : public SBarInfoCommand void Negate() { - swapvalues(commands[0], commands[1]); + std::swap(commands[0], commands[1]); } private: diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index fa809240f..b78edbafe 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -2251,13 +2251,13 @@ static int PatchText (int oldSize) // This must be done because the map is scanned using a binary search. while (i > 0 && strncmp (DehSpriteMappings[i-1].Sprite, newStr, 4) > 0) { - swapvalues (DehSpriteMappings[i-1], DehSpriteMappings[i]); + std::swap (DehSpriteMappings[i-1], DehSpriteMappings[i]); --i; } while ((size_t)i < countof(DehSpriteMappings)-1 && strncmp (DehSpriteMappings[i+1].Sprite, newStr, 4) < 0) { - swapvalues (DehSpriteMappings[i+1], DehSpriteMappings[i]); + std::swap (DehSpriteMappings[i+1], DehSpriteMappings[i]); ++i; } break; diff --git a/src/gamedata/textures/anim_switches.cpp b/src/gamedata/textures/anim_switches.cpp index 24ac8aad8..2b2f702f4 100644 --- a/src/gamedata/textures/anim_switches.cpp +++ b/src/gamedata/textures/anim_switches.cpp @@ -268,7 +268,7 @@ FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad) max = sc.Number & 65535; if (min > max) { - swapvalues (min, max); + std::swap (min, max); } thisframe.TimeMin = min; thisframe.TimeRnd = (max - min + 1); diff --git a/src/gamedata/textures/animations.cpp b/src/gamedata/textures/animations.cpp index 0132fc336..51ed32782 100644 --- a/src/gamedata/textures/animations.cpp +++ b/src/gamedata/textures/animations.cpp @@ -254,7 +254,7 @@ void FTextureManager::InitAnimated (void) // [RH] Allow for backward animations as well as forward. else if (pic1 > pic2) { - swapvalues (pic1, pic2); + std::swap (pic1, pic2); animtype = FAnimDef::ANIM_Backward; } @@ -485,7 +485,7 @@ FAnimDef *FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, ETex { type = FAnimDef::ANIM_Backward; Texture(framenum)->bNoDecals = Texture(picnum)->bNoDecals; - swapvalues (framenum, picnum); + std::swap (framenum, picnum); } FAnimDef *ani = AddSimpleAnim (picnum, framenum - picnum + 1, min, max - min); if (ani != NULL) ani->AnimType = type; diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index e021ba843..cad9d0939 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -2410,7 +2410,7 @@ void MapLoader::CreateBlockMap () { if (bx > bx2) { - swapvalues (block, endblock); + std::swap (block, endblock); } do { @@ -2422,7 +2422,7 @@ void MapLoader::CreateBlockMap () { if (by > by2) { - swapvalues (block, endblock); + std::swap (block, endblock); } do { diff --git a/src/playsim/p_acs.cpp b/src/playsim/p_acs.cpp index 5ba454856..dd958c6b4 100644 --- a/src/playsim/p_acs.cpp +++ b/src/playsim/p_acs.cpp @@ -2838,7 +2838,7 @@ void FBehavior::LoadScriptsDirectory () // Make the closed version the first one. if (Scripts[i+1].Type == SCRIPT_Closed) { - swapvalues(Scripts[i], Scripts[i+1]); + std::swap(Scripts[i], Scripts[i+1]); } } } @@ -3585,7 +3585,7 @@ int DLevelScript::Random (int min, int max) { if (max < min) { - swapvalues (max, min); + std::swap (max, min); } return min + pr_acs(max - min + 1); @@ -5149,7 +5149,7 @@ int DLevelScript::SwapActorTeleFog(AActor *activator, int tid) if ((activator == NULL) || (activator->TeleFogSourceType == activator->TeleFogDestType)) return 0; //Does nothing if they're the same. - swapvalues (activator->TeleFogSourceType, activator->TeleFogDestType); + std::swap (activator->TeleFogSourceType, activator->TeleFogDestType); return 1; } else @@ -5162,7 +5162,7 @@ int DLevelScript::SwapActorTeleFog(AActor *activator, int tid) if (actor->TeleFogSourceType == actor->TeleFogDestType) continue; //They're the same. Save the effort. - swapvalues (actor->TeleFogSourceType, actor->TeleFogDestType); + std::swap (actor->TeleFogSourceType, actor->TeleFogDestType); count++; } } @@ -6956,7 +6956,7 @@ int DLevelScript::RunScript() break; case PCD_SWAP: - swapvalues(Stack[sp-2], Stack[sp-1]); + std::swap(Stack[sp-2], Stack[sp-1]); break; case PCD_LSPEC1: diff --git a/src/playsim/p_enemy.cpp b/src/playsim/p_enemy.cpp index 5d9191900..88e0f37ac 100644 --- a/src/playsim/p_enemy.cpp +++ b/src/playsim/p_enemy.cpp @@ -728,7 +728,7 @@ void P_DoNewChaseDir (AActor *actor, double deltax, double deltay) { if ((pr_newchasedir() > 200 || fabs(deltay) > fabs(deltax))) { - swapvalues (d[0], d[1]); + std::swap (d[0], d[1]); } if (d[0] == turnaround) @@ -1041,7 +1041,7 @@ void P_RandomChaseDir (AActor *actor) // try other directions if (pr_newchasedir() > 200 || fabs(delta.Y) > fabs(delta.X)) { - swapvalues (d[1], d[2]); + std::swap (d[1], d[2]); } if (d[1] == turnaround) diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index ed5ce9bc3..a6007ce38 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -413,8 +413,8 @@ bool FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2) if (start > end) { - swapvalues (start, end); - swapvalues (pal1, pal2); + std::swap (start, end); + std::swap (pal1, pal2); } else if (start == end) { @@ -461,7 +461,7 @@ bool FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, in if (start > end) { - swapvalues (start, end); + std::swap (start, end); r = r2; g = g2; b = b2; @@ -524,10 +524,10 @@ bool FRemapTable::AddDesaturation(int start, int end, double r1, double g1, doub if (start > end) { - swapvalues(start, end); - swapvalues(r1, r2); - swapvalues(g1, g2); - swapvalues(b1, b2); + std::swap(start, end); + std::swap(r1, r2); + std::swap(g1, g2); + std::swap(b1, b2); } r2 -= r1; diff --git a/src/r_data/v_palette.cpp b/src/r_data/v_palette.cpp index 4135fab12..dc5600d9a 100644 --- a/src/r_data/v_palette.cpp +++ b/src/r_data/v_palette.cpp @@ -172,7 +172,7 @@ void FPalette::MakeGoodRemap () if (new0 > dup) { // Make the lower-numbered entry a copy of color 0. (Just because.) - swapvalues (new0, dup); + std::swap (new0, dup); } Remap[0] = new0; Remap[new0] = dup; diff --git a/src/r_data/v_palette.h b/src/r_data/v_palette.h index dbabd92e8..e6fe51b3c 100644 --- a/src/r_data/v_palette.h +++ b/src/r_data/v_palette.h @@ -36,7 +36,7 @@ #include "doomtype.h" #include "c_cvars.h" -#include "palette.h" +#include "palutil.h" struct FPalette { diff --git a/src/rendering/swrenderer/line/r_wallsetup.cpp b/src/rendering/swrenderer/line/r_wallsetup.cpp index 8dbef5300..b126cbe34 100644 --- a/src/rendering/swrenderer/line/r_wallsetup.cpp +++ b/src/rendering/swrenderer/line/r_wallsetup.cpp @@ -65,7 +65,7 @@ namespace swrenderer float t = -tleft.X; tleft.X = -tright.X; tright.X = t; - swapvalues(tleft.Y, tright.Y); + std::swap(tleft.Y, tright.Y); } float fsx1, fsz1, fsx2, fsz2; diff --git a/src/rendering/swrenderer/scene/r_opaque_pass.cpp b/src/rendering/swrenderer/scene/r_opaque_pass.cpp index 2674e782d..a0ad219f7 100644 --- a/src/rendering/swrenderer/scene/r_opaque_pass.cpp +++ b/src/rendering/swrenderer/scene/r_opaque_pass.cpp @@ -399,7 +399,7 @@ namespace swrenderer double t = -rx1; rx1 = -rx2; rx2 = t; - swapvalues(ry1, ry2); + std::swap(ry1, ry2); } auto viewport = Thread->Viewport.get(); diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 702f2b8f1..993e9d469 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -148,7 +148,7 @@ void FCompileContext::CheckReturn(PPrototype *proto, FScriptPosition &pos) if (ReturnProto->ReturnTypes.Size() < proto->ReturnTypes.Size()) { // Make proto the shorter one to avoid code duplication below. - swapvalues(proto, ReturnProto); + std::swap(proto, ReturnProto); swapped = true; } // If one prototype returns nothing, they both must. @@ -165,7 +165,7 @@ void FCompileContext::CheckReturn(PPrototype *proto, FScriptPosition &pos) { PType* expected = ReturnProto->ReturnTypes[i]; PType* actual = proto->ReturnTypes[i]; - if (swapped) swapvalues(expected, actual); + if (swapped) std::swap(expected, actual); if (expected != actual && !AreCompatiblePointerTypes(expected, actual)) { // Incompatible @@ -2917,7 +2917,7 @@ ExpEmit FxAddSub::Emit(VMFunctionBuilder *build) // Since addition is commutative, only the second operand may be a constant. if (op1.Konst) { - swapvalues(op1, op2); + std::swap(op1, op2); } assert(!op1.Konst); op1.Free(build); @@ -3156,7 +3156,7 @@ ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build) assert(Operator != '%'); if (right->IsVector()) { - swapvalues(op1, op2); + std::swap(op1, op2); } int op; if (op2.Konst) @@ -3179,7 +3179,7 @@ ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build) // Multiplication is commutative, so only the second operand may be constant. if (op1.Konst) { - swapvalues(op1, op2); + std::swap(op1, op2); } assert(!op1.Konst); op1.Free(build); @@ -3811,7 +3811,7 @@ ExpEmit FxCompareEq::EmitCommon(VMFunctionBuilder *build, bool forcompare, bool // Only the second operand may be constant. if (op1.Konst) { - swapvalues(op1, op2); + std::swap(op1, op2); } assert(!op1.Konst); assert(op1.RegCount >= 1 && op1.RegCount <= 3); @@ -3934,7 +3934,7 @@ ExpEmit FxBitOp::Emit(VMFunctionBuilder *build) op2 = right->Emit(build); if (op1.Konst) { - swapvalues(op1, op2); + std::swap(op1, op2); } assert(!op1.Konst); rop = op2.RegNum; diff --git a/src/scripting/decorate/thingdef_states.cpp b/src/scripting/decorate/thingdef_states.cpp index cede46bdd..a16e62b77 100644 --- a/src/scripting/decorate/thingdef_states.cpp +++ b/src/scripting/decorate/thingdef_states.cpp @@ -247,7 +247,7 @@ do_stop: sc.MustGetStringName(")"); if (min > max) { - swapvalues(min, max); + std::swap(min, max); } state.Tics = min; state.TicRange = max - min; diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 8f9916818..ca1679ea5 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -1400,7 +1400,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorrange, I_I, PlayerPawn) PROP_INT_PARM(end, 1); if (start > end) - swapvalues (start, end); + std::swap (start, end); defaults->IntVar(NAME_ColorRangeStart) = start; defaults->IntVar(NAME_ColorRangeEnd) = end; diff --git a/src/utility/colormatcher.h b/src/utility/colormatcher.h index c9623c664..9d0826ea4 100644 --- a/src/utility/colormatcher.h +++ b/src/utility/colormatcher.h @@ -40,7 +40,7 @@ #ifndef __COLORMATCHER_H__ #define __COLORMATCHER_H__ -#include "palette.h" +#include "palutil.h" int BestColor (const uint32_t *pal_in, int r, int g, int b, int first, int num); diff --git a/src/utility/m_alloc.cpp b/src/utility/m_alloc.cpp index 214bba141..755e7b1b5 100644 --- a/src/utility/m_alloc.cpp +++ b/src/utility/m_alloc.cpp @@ -44,7 +44,7 @@ #include #endif -#include "doomerrors.h" +#include "printf.h" #include "m_alloc.h" #ifndef _MSC_VER diff --git a/src/utility/m_alloc.h b/src/utility/m_alloc.h index 75c9d6cb9..3da124bff 100644 --- a/src/utility/m_alloc.h +++ b/src/utility/m_alloc.h @@ -35,6 +35,7 @@ #define __M_ALLOC_H__ #include +#include #if defined(__APPLE__) #define _msize(p) malloc_size(p) @@ -49,16 +50,32 @@ // when they can't get the memory. #if defined(_DEBUG) +#define M_Calloc(s,t) M_Calloc_Dbg(s, t, __FILE__, __LINE__) #define M_Malloc(s) M_Malloc_Dbg(s, __FILE__, __LINE__) #define M_Realloc(p,s) M_Realloc_Dbg(p, s, __FILE__, __LINE__) void *M_Malloc_Dbg (size_t size, const char *file, int lineno); void *M_Realloc_Dbg (void *memblock, size_t size, const char *file, int lineno); +inline void* M_Calloc_Dbg(size_t v1, size_t v2, const char* file, int lineno) +{ + auto p = M_Malloc_Dbg(v1 * v2, file, lineno); + memset(p, 0, v1 * v2); + return p; +} + #else void *M_Malloc (size_t size); void *M_Realloc (void *memblock, size_t size); +inline void* M_Calloc(size_t v1, size_t v2) +{ + auto p = M_Malloc(v1 * v2); + memset(p, 0, v1 * v2); + return p; +} + #endif + void M_Free (void *memblock); #endif //__M_ALLOC_H__ diff --git a/src/utility/memarena.cpp b/src/utility/memarena.cpp index b08828d73..f576d49fa 100644 --- a/src/utility/memarena.cpp +++ b/src/utility/memarena.cpp @@ -41,6 +41,7 @@ #include "memarena.h" #include "printf.h" #include "cmdlib.h" +#include "m_alloc.h" struct FMemArena::Block { diff --git a/src/utility/name.cpp b/src/utility/name.cpp index de56772c4..a34575df7 100644 --- a/src/utility/name.cpp +++ b/src/utility/name.cpp @@ -34,9 +34,9 @@ #include #include "name.h" -#include "c_dispatch.h" -#include "c_console.h" +#include "superfasthash.h" #include "cmdlib.h" +#include "m_alloc.h" // MACROS ------------------------------------------------------------------ @@ -270,7 +270,7 @@ FName::NameManager::~NameManager() { NameBlock *block, *next; - C_ClearTabCommands(); + //C_ClearTabCommands(); for (block = Blocks; block != NULL; block = next) { diff --git a/src/utility/name.h b/src/utility/name.h index 76324fe7c..ecc9c36bf 100644 --- a/src/utility/name.h +++ b/src/utility/name.h @@ -34,6 +34,8 @@ #ifndef NAME_H #define NAME_H +#include "tarray.h" + enum ENamedName { #define xx(n) NAME_##n, @@ -122,4 +124,13 @@ protected: static NameManager NameData; }; + +template<> struct THashTraits +{ + hash_t Hash(FName key) + { + return key.GetIndex(); + } + int Compare(FName left, FName right) { return left != right; } +}; #endif diff --git a/src/utility/nodebuilder/nodebuild.cpp b/src/utility/nodebuilder/nodebuild.cpp index 8955060ff..a097efd43 100644 --- a/src/utility/nodebuilder/nodebuild.cpp +++ b/src/utility/nodebuilder/nodebuild.cpp @@ -392,7 +392,7 @@ bool FNodeBuilder::CheckSubsectorOverlappingSegs (uint32_t set, node_t &node, ui { if (Segs[seg2].linedef == -1) { // Do not put minisegs into a new subsector. - swapvalues (seg1, seg2); + std::swap (seg1, seg2); } D(Printf(PRINT_LOG, "Need to synthesize a splitter for set %d on seg %d (ov)\n", set, seg2)); splitseg = UINT_MAX; diff --git a/src/utility/palentry.h b/src/utility/palentry.h index 8f4bfa6d8..4064f4ac7 100644 --- a/src/utility/palentry.h +++ b/src/utility/palentry.h @@ -1,7 +1,14 @@ #pragma once +#include #include +// Beware of windows.h :( +#ifdef max +#undef min +#undef max +#endif + struct PalEntry { PalEntry() = default; @@ -34,6 +41,11 @@ struct PalEntry return (r * 77 + g * 143 + b * 37) >> 8; } + int Amplitude() const + { + return std::max(r, std::max(g, b)); + } + void Decolorize() // this for 'nocoloredspritelighting' and not the same as desaturation. The normal formula results in a value that's too dark. { int v = (r + g + b); @@ -80,3 +92,9 @@ inline int Luminance(int r, int g, int b) return (r * 77 + g * 143 + b * 37) >> 8; } +#define APART(c) (((c)>>24)&0xff) +#define RPART(c) (((c)>>16)&0xff) +#define GPART(c) (((c)>>8)&0xff) +#define BPART(c) ((c)&0xff) +#define MAKERGB(r,g,b) uint32_t(((r)<<16)|((g)<<8)|(b)) +#define MAKEARGB(a,r,g,b) uint32_t(((a)<<24)|((r)<<16)|((g)<<8)|(b)) diff --git a/src/utility/palette.cpp b/src/utility/palette.cpp index e79e68a54..05bca1510 100644 --- a/src/utility/palette.cpp +++ b/src/utility/palette.cpp @@ -32,7 +32,7 @@ ** */ -#include "palette.h" +#include "palutil.h" #include "palentry.h" /****************************/ diff --git a/src/utility/palette.h b/src/utility/palutil.h similarity index 67% rename from src/utility/palette.h rename to src/utility/palutil.h index 3e7c2f5eb..b06712777 100644 --- a/src/utility/palette.h +++ b/src/utility/palutil.h @@ -3,14 +3,6 @@ #include struct PalEntry; -#define MAKERGB(r,g,b) uint32_t(((r)<<16)|((g)<<8)|(b)) -#define MAKEARGB(a,r,g,b) uint32_t(((a)<<24)|((r)<<16)|((g)<<8)|(b)) - -#define APART(c) (((c)>>24)&0xff) -#define RPART(c) (((c)>>16)&0xff) -#define GPART(c) (((c)>>8)&0xff) -#define BPART(c) ((c)&0xff) - int BestColor(const uint32_t* pal, int r, int g, int b, int first = 1, int num = 255); int PTM_BestColor(const uint32_t* pal_in, int r, int g, int b, bool reverselookup, float powtable, int first = 1, int num = 255); void DoBlending(const PalEntry* from, PalEntry* to, int count, int r, int g, int b, int a); diff --git a/src/utility/printf.h b/src/utility/printf.h index 51f010443..70681004c 100644 --- a/src/utility/printf.h +++ b/src/utility/printf.h @@ -24,6 +24,7 @@ enum PRINT_TYPES = 1023, // Bitmask. 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/src/utility/s_playlist.cpp b/src/utility/s_playlist.cpp index 8b8be5f76..fcec0506c 100644 --- a/src/utility/s_playlist.cpp +++ b/src/utility/s_playlist.cpp @@ -156,7 +156,7 @@ void FPlayList::Shuffle () for (i = 0; i < numsongs; ++i) { - swapvalues (Songs[i], Songs[(rand() % (numsongs - i)) + i]); + std::swap (Songs[i], Songs[(rand() % (numsongs - i)) + i]); } Position = 0; } diff --git a/src/utility/stats.cpp b/src/utility/stats.cpp index 817d1fe8b..7c3d4815a 100644 --- a/src/utility/stats.cpp +++ b/src/utility/stats.cpp @@ -78,6 +78,15 @@ void FStat::ToggleStat (const char *name) Printf ("Unknown stat: %s\n", name); } +void FStat::EnableStat(const char* name, bool on) +{ + FStat* stat = FindStat(name); + if (stat) + stat->m_Active = on; + else + Printf("Unknown stat: %s\n", name); +} + void FStat::ToggleStat () { m_Active = !m_Active; @@ -88,7 +97,7 @@ void FStat::PrintStat () int textScale = active_con_scale(); int fontheight = NewConsoleFont->GetHeight() + 1; - int y = SCREENHEIGHT / textScale; + int y = screen->GetHeight() / textScale; int count = 0; for (FStat *stat = FirstStat; stat != NULL; stat = stat->m_Next) diff --git a/src/utility/stats.h b/src/utility/stats.h index ec963f534..1a01b674c 100644 --- a/src/utility/stats.h +++ b/src/utility/stats.h @@ -241,6 +241,7 @@ public: static void PrintStat (); static FStat *FindStat (const char *name); static void ToggleStat (const char *name); + static void EnableStat(const char* name, bool on); static void DumpRegisteredStats (); private: diff --git a/src/utility/superfasthash.cpp b/src/utility/superfasthash.cpp new file mode 100644 index 000000000..a443809f0 --- /dev/null +++ b/src/utility/superfasthash.cpp @@ -0,0 +1,127 @@ +#include +#include +#include + +/* ======================================================================== */ + +/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh derivative + license. See: + http://www.azillionmonkeys.com/qed/weblicense.html for license details. + + http://www.azillionmonkeys.com/qed/hash.html */ + +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif + +uint32_t SuperFastHash (const char *data, size_t len) +{ + uint32_t hash = 0, tmp; + size_t rem; + + if (len == 0 || data == NULL) return 0; + + rem = len & 3; + len >>= 2; + + /* Main loop */ + for (;len > 0; len--) + { + hash += get16bits (data); + tmp = (get16bits (data+2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2*sizeof (uint16_t); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) + { + case 3: hash += get16bits (data); + hash ^= hash << 16; + hash ^= data[sizeof (uint16_t)] << 18; + hash += hash >> 11; + break; + case 2: hash += get16bits (data); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: hash += *data; + hash ^= hash << 10; + hash += hash >> 1; + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +} + +/* A modified version to do a case-insensitive hash */ + +#undef get16bits +#define get16bits(d) ((((uint32_t)tolower(((const uint8_t *)(d))[1])) << 8)\ + +(uint32_t)tolower(((const uint8_t *)(d))[0]) ) + +uint32_t SuperFastHashI (const char *data, size_t len) +{ + uint32_t hash = 0, tmp; + size_t rem; + + if (len <= 0 || data == NULL) return 0; + + rem = len & 3; + len >>= 2; + + /* Main loop */ + for (;len > 0; len--) + { + hash += get16bits (data); + tmp = (get16bits (data+2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2*sizeof (uint16_t); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) + { + case 3: hash += get16bits (data); + hash ^= hash << 16; + hash ^= tolower(data[sizeof (uint16_t)]) << 18; + hash += hash >> 11; + break; + case 2: hash += get16bits (data); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: hash += tolower(*data); + hash ^= hash << 10; + hash += hash >> 1; + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; +} + +/* ======================================================================== */ + diff --git a/src/utility/superfasthash.h b/src/utility/superfasthash.h index d6b7dae0c..972025202 100644 --- a/src/utility/superfasthash.h +++ b/src/utility/superfasthash.h @@ -1,5 +1,20 @@ #pragma once +#include + +uint32_t SuperFastHash (const char *data, size_t len); +uint32_t SuperFastHashI (const char *data, size_t len); + +inline unsigned int MakeKey(const char* s) +{ + if (s == NULL) + { + return 0; + } + return SuperFastHashI(s, strlen(s)); +} + +inline unsigned int MakeKey(const char* s, size_t len) +{ + return SuperFastHashI(s, len); +} -extern unsigned int MakeKey (const char *s); -extern unsigned int MakeKey (const char *s, size_t len); -extern unsigned int SuperFastHash (const char *data, size_t len); diff --git a/src/utility/tarray.h b/src/utility/tarray.h index 32ccc50ce..7bafeb9ee 100644 --- a/src/utility/tarray.h +++ b/src/utility/tarray.h @@ -257,14 +257,17 @@ public: } return true; } - // Return a reference to an element + // Return a reference to an element. + // Note that the asserts must let the element after the end pass because this gets frequently used as a sentinel pointer. T &operator[] (size_t index) const { + assert(index <= Count); return Array[index]; } // Returns the value of an element TT operator() (size_t index) const { + assert(index <= Count); return Array[index]; } // Returns a reference to the last element @@ -1419,9 +1422,15 @@ public: { } - BitArray(const BitArray & arr) + BitArray(unsigned elem) + : bytes((elem + 7) / 8, true) + { + + } + + BitArray(const BitArray & arr) + : bytes(arr.bytes) { - bytes = arr.bytes; size = arr.size; } @@ -1433,8 +1442,8 @@ public: } BitArray(BitArray && arr) + : bytes(std::move(arr.bytes)) { - bytes = std::move(arr.bytes); size = arr.size; arr.size = 0; } @@ -1452,9 +1461,10 @@ public: return !!(bytes[index >> 3] & (1 << (index & 7))); } - void Set(size_t index) + void Set(size_t index, bool set = true) { - bytes[index >> 3] |= (1 << (index & 7)); + if (!set) Clear(index); + else bytes[index >> 3] |= (1 << (index & 7)); } void Clear(size_t index) @@ -1474,6 +1484,51 @@ public: }; +template +class FixedBitArray +{ + uint8_t bytes[(size + 7) / 8]; + +public: + + FixedBitArray() = default; + FixedBitArray(bool set) + { + memset(bytes, set ? -1 : 0, sizeof(bytes)); + } + + bool operator[](size_t index) const + { + return !!(bytes[index >> 3] & (1 << (index & 7))); + } + + void Set(size_t index, bool set = true) + { + if (!set) Clear(index); + else bytes[index >> 3] |= (1 << (index & 7)); + } + + void Clear(size_t index) + { + bytes[index >> 3] &= ~(1 << (index & 7)); + } + + constexpr unsigned Size() const + { + return size; + } + + void Zero() + { + memset(&bytes[0], 0, sizeof(bytes)); + } + + void SetAll(bool on) + { + memset(&bytes[0], on ? -1 : 0, sizeof(bytes)); + } +}; + // A wrapper to externally stored data. // I would have expected something for this in the stl, but std::span is only in C++20. template diff --git a/src/utility/templates.h b/src/utility/templates.h index 0737fc4e9..48d306cf8 100644 --- a/src/utility/templates.h +++ b/src/utility/templates.h @@ -41,6 +41,7 @@ #include #include +#include //========================================================================== // @@ -92,58 +93,6 @@ const ClassType *BinarySearch (const ClassType *first, int max, return NULL; } -//========================================================================== -// -// BinarySearchFlexible -// -// THIS DOES NOT WORK RIGHT WITH VISUAL C++ -// ONLY ONE COMPTYPE SEEMS TO BE USED FOR ANY INSTANCE OF THIS FUNCTION -// IN A DEBUG BUILD. RELEASE MIGHT BE DIFFERENT--I DIDN'T BOTHER TRYING. -// -// Similar to BinarySearch, except another function is used to copmare -// items in the array. -// -// Template parameters: -// IndexType - The type used to index the array (int, size_t, etc.) -// KeyType - The type of the key -// CompType - A class with a static DoCompare(IndexType, KeyType) method. -// -// Function parameters: -// max - The number of elements in the array -// key - The key value to look for -// noIndex - The value to return if no matching element is found. -// -// Returns: -// The index of the matching element or noIndex. -//========================================================================== - -template -inline -IndexType BinarySearchFlexible (IndexType max, const KeyType key, IndexType noIndex) -{ - IndexType min = 0; - --max; - - while (min <= max) - { - IndexType mid = (min + max) / 2; - int lexx = CompType::DoCompare (mid, key); - if (lexx == 0) - { - return mid; - } - else if (lexx < 0) - { - min = mid + 1; - } - else - { - max = mid - 1; - } - } - return noIndex; -} - //========================================================================== // // MIN @@ -194,18 +143,4 @@ T clamp (const T in, const T min, const T max) return in <= min ? min : in >= max ? max : in; } -//========================================================================== -// -// swapvalues -// -// Swaps the values of a and b. -//========================================================================== - -template -inline -void swapvalues (T &a, T &b) -{ - T temp = std::move(a); a = std::move(b); b = std::move(temp); -} - #endif //__TEMPLATES_H__ diff --git a/src/utility/tflags.h b/src/utility/tflags.h index 18c2becaf..98516fce8 100644 --- a/src/utility/tflags.h +++ b/src/utility/tflags.h @@ -32,7 +32,6 @@ */ #pragma once -#include "doomtype.h" /* * TFlags diff --git a/src/utility/zstring.cpp b/src/utility/zstring.cpp index 0f7a0bd10..2cd308596 100644 --- a/src/utility/zstring.cpp +++ b/src/utility/zstring.cpp @@ -38,9 +38,10 @@ #include // for bad_alloc #include "zstring.h" -#include "v_text.h" #include "utf8.h" -#include "fontinternals.h" + +extern uint16_t lowerforupper[65536]; +extern uint16_t upperforlower[65536]; FNullStringData FString::NullString = { diff --git a/src/utility/zstring.h b/src/utility/zstring.h index d7a9417ef..4b636ac77 100644 --- a/src/utility/zstring.h +++ b/src/utility/zstring.h @@ -37,6 +37,7 @@ #include #include #include +#include #include "tarray.h" #include "name.h" @@ -403,6 +404,7 @@ public: return Compare(other) >= 0; } + // These are needed to block the default char * conversion operator from making a mess. bool operator == (const char *) const = delete; bool operator != (const char *) const = delete; bool operator < (const char *) const = delete; @@ -420,6 +422,7 @@ public: private: }; +// These are also needed to block the default char * conversion operator from making a mess. bool operator == (const char *, const FString &) = delete; bool operator != (const char *, const FString &) = delete; bool operator < (const char *, const FString &) = delete; @@ -481,10 +484,19 @@ inline FName::FName(const FString &text, bool noCreate) { Index = NameData.FindN 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) -extern unsigned int SuperFastHash (const char *data, size_t len); +#include "superfasthash.h" + template<> struct THashTraits { hash_t Hash(const FString &key) { return (hash_t)SuperFastHash(key.GetChars(), key.Len()); } // Compares two keys, returning zero if they are the same. int Compare(const FString &left, const FString &right) { return left.Compare(right); } }; + +struct StringNoCaseHashTraits +{ + hash_t Hash(const FString& key) { return (hash_t)SuperFastHashI(key.GetChars(), key.Len()); } + // Compares two keys, returning zero if they are the same. + int Compare(const FString& left, const FString& right) { return left.CompareNoCase(right); } +}; + diff --git a/src/win32/i_dijoy.cpp b/src/win32/i_dijoy.cpp index 4a435d8d8..4374cfca5 100644 --- a/src/win32/i_dijoy.cpp +++ b/src/win32/i_dijoy.cpp @@ -645,7 +645,7 @@ bool FDInputJoystick::ReorderAxisPair(const GUID &xid, const GUID &yid, int pos) } if (x == pos + 1 && y == pos) { // Xbox 360 Controllers return them in this order. - swapvalues(Axes[pos], Axes[pos + 1]); + std::swap(Axes[pos], Axes[pos + 1]); } else if (x != pos || y != pos + 1) { diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 075909b7f..547ae4848 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -439,7 +439,7 @@ static void DoPrintStr(const char *cpt, HWND edit, HANDLE StdOut) if (edit != NULL) { // GDI uses BGR colors, but color is RGB, so swap the R and the B. - swapvalues(color.r, color.b); + std::swap(color.r, color.b); // Change the color. format.cbSize = sizeof(format); format.dwMask = CFM_COLOR;