diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 6234c1d30b..0215f62f7d 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,6 @@ +March 24, 2007 +- Changed MakeKey's hash algorithm from a CRC32 to Paul Hsieh's SuperFastHash. + March 20, 2007 - Moved the implementation for the Thing_Damage special into another function so that I can create the ACS function Thing_Damage2. It's exactly the same as diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 1403dac6be..6453a6068e 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -3,7 +3,7 @@ ** Functions for executing console commands and aliases ** **--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit +** Copyright 1998-2007 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -32,6 +32,8 @@ ** */ +// HEADER FILES ------------------------------------------------------------ + #include #include #include @@ -51,24 +53,9 @@ #include "m_crc32.h" #include "v_text.h" -bool ParsingKeyConf; +// MACROS ------------------------------------------------------------------ -static const char *KeyConfCommands[] = -{ - "alias", - "defaultbind", - "addkeysection", - "addmenukey", - "addslotdefault", - "weaponsection", - "setslot", - "addplayerclass", - "clearplayerclasses" -}; - -static long ParseCommandLine (const char *args, int *argc, char **argv); - -CVAR (Bool, lookspring, true, CVAR_ARCHIVE); // Generate centerview when -mlook encountered? +// TYPES ------------------------------------------------------------------- class DWaitingCommand : public DThinker { @@ -108,51 +95,78 @@ struct FActionMap char Name[12]; }; +// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +static long ParseCommandLine (const char *args, int *argc, char **argv); static FConsoleCommand *FindNameInHashTable (FConsoleCommand **table, const char *name, size_t namelen); static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *name, size_t namelen, FConsoleCommand **prev); -FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE]; +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +CVAR (Bool, lookspring, true, CVAR_ARCHIVE); // Generate centerview when -mlook encountered? + +FConsoleCommand *Commands[FConsoleCommand::HASH_SIZE]; FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack, Button_Attack, Button_Speed, Button_MoveRight, Button_MoveLeft, Button_Strafe, Button_LookDown, Button_LookUp, Button_Back, Button_Forward, Button_Right, Button_Left, Button_MoveDown, Button_MoveUp, Button_Jump, Button_ShowScores, Button_Crouch; +bool ParsingKeyConf; + // To add new actions, go to the console and type "key ". // This will give you the key value to use in the first column. Then // insert your new action into this list so that the keys remain sorted // in ascending order. No two keys can be identical. If yours matches -// an existing key, either modify MakeKey(), or (preferably) change the -// name of your action. +// an existing key, change the name of your action. FActionMap ActionMaps[] = { - { 0x0f26fef6, &Button_Speed, "speed" }, - { 0x1ccf57bf, &Button_MoveUp, "moveup" }, - { 0x22beba5f, &Button_Klook, "klook" }, - { 0x47c02d3b, &Button_Attack, "attack" }, - { 0x6dcec137, &Button_Back, "back" }, - { 0x7a67e768, &Button_Left, "left" }, - { 0x8076f318, &Button_Crouch, "crouch" }, - { 0x84b8789a, &Button_MoveLeft, "moveleft" }, - { 0x8fd9bf1e, &Button_ShowScores, "showscores" }, - { 0x94b1cc4b, &Button_Use, "use" }, - { 0xa7b30616, &Button_Jump, "jump" }, - { 0xadfe4fff, &Button_Mlook, "mlook" }, - { 0xb4ca7514, &Button_Right, "right" }, - { 0xb563e265, &Button_LookDown, "lookdown" }, - { 0xb67a0835, &Button_Strafe, "strafe" }, - { 0xc4704c1d, &Button_AltAttack, "altattack" }, - { 0xe2200fc9, &Button_MoveDown, "movedown" }, - { 0xe78739bb, &Button_MoveRight, "moveright" }, - { 0xe7912f86, &Button_Forward, "forward" }, - { 0xf01cb105, &Button_LookUp, "lookup" }, + { 0x1eefa611, &Button_Jump, "jump" }, + { 0x201f1c55, &Button_Right, "right" }, + { 0x23a99cd7, &Button_Back, "back" }, + { 0x4463f43a, &Button_LookDown, "lookdown" }, + { 0x5622bf42, &Button_Attack, "attack" }, + { 0x57c25cb2, &Button_Klook, "klook" }, + { 0x59f3e907, &Button_Forward, "forward" }, + { 0x6167ce99, &Button_MoveDown, "movedown" }, + { 0x676885b8, &Button_AltAttack, "altattack" }, + { 0x6fa41b84, &Button_MoveLeft, "moveleft" }, + { 0x818f08e6, &Button_MoveRight, "moveright" }, + { 0xa2b62d8b, &Button_Mlook, "mlook" }, + { 0xab2c3e71, &Button_Crouch, "crouch" }, + { 0xb000b483, &Button_Left, "left" }, + { 0xb62b1e49, &Button_LookUp, "lookup" }, + { 0xb7e6a54b, &Button_Strafe, "strafe" }, + { 0xd5897c73, &Button_ShowScores, "showscores" }, + { 0xe0ccb317, &Button_Speed, "speed" }, + { 0xe0cfc260, &Button_Use, "use" }, + { 0xfdd701c7, &Button_MoveUp, "moveup" }, }; - #define NUM_ACTIONS countof(ActionMaps) +// PRIVATE DATA DEFINITIONS ------------------------------------------------ +static const char *KeyConfCommands[] = +{ + "alias", + "defaultbind", + "addkeysection", + "addmenukey", + "addslotdefault", + "weaponsection", + "setslot", + "addplayerclass", + "clearplayerclasses" +}; + +// CODE -------------------------------------------------------------------- IMPLEMENT_CLASS (DWaitingCommand) @@ -247,39 +261,141 @@ 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 WORD *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((DWORD)(((const BYTE *)(d))[1])) << 8)\ + +(DWORD)(((const BYTE *)(d))[0]) ) +#endif + +DWORD SuperFastHash (const char *data, size_t len) +{ + DWORD 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 (WORD); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) + { + case 3: hash += get16bits (data); + hash ^= hash << 16; + hash ^= data[sizeof (WORD)] << 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) ((((DWORD)tolower(((const BYTE *)(d))[1])) << 8)\ + +(DWORD)tolower(((const BYTE *)(d))[0]) ) + +DWORD SuperFastHashI (const char *data, size_t len) +{ + DWORD 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 (WORD); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) + { + case 3: hash += get16bits (data); + hash ^= hash << 16; + hash ^= tolower(data[sizeof (WORD)]) << 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 0xffffffff; + return 0; } - - DWORD key = 0xffffffff; - const DWORD *table = GetCRCTable (); - - while (*s) - { - key = CRC1 (key, tolower (*s++), table); - } - return key ^ 0xffffffff; + return SuperFastHashI (s, strlen (s)); } unsigned int MakeKey (const char *s, size_t len) { - if (len == 0 || s == NULL) - { - return 0xffffffff; - } - - DWORD key = 0xffffffff; - const DWORD *table = GetCRCTable (); - - while (len > 0) - { - key = CRC1 (key, tolower(*s++), table); - --len; - } - return key ^ 0xffffffff; + return SuperFastHashI (s, len); } // FindButton scans through the actionbits[] array @@ -764,9 +880,6 @@ bool FConsoleCommand::AddToHash (FConsoleCommand **table) unsigned int key; FConsoleCommand *insert, **bucket; - if (!stricmp (m_Name, "toggle")) - key = 1; - key = MakeKey (m_Name); bucket = &table[key % HASH_SIZE]; diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index bac9d73477..4484e94c28 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -146,12 +146,6 @@ void PClass::InsertIntoHash () *hashpos = this; } -// Find a type, passed the name as a string -const PClass *PClass::FindClass (const char *zaname) -{ - return FindClass (FName (zaname, true)); -} - // Find a type, passed the name as a name const PClass *PClass::FindClass (FName zaname) { diff --git a/src/dobjtype.h b/src/dobjtype.h index 773ccacb87..88f832f9a0 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -127,7 +127,10 @@ struct PClass return ti->IsAncestorOf (this); } - static const PClass *FindClass (const char *name); + // Find a type, given its name. + static const PClass *FindClass (const char *name) { return FindClass (FName (name, true)); } + static const PClass *FindClass (const FString &name) { return FindClass (FName (name, true)); } + static const PClass *FindClass (ENamedName name) { return FindClass (FName (name)); } static const PClass *FindClass (FName name); static TArray m_Types; diff --git a/src/empty.cpp b/src/empty.cpp index 87773c6b77..7949ebd7e4 100644 --- a/src/empty.cpp +++ b/src/empty.cpp @@ -32,3 +32,28 @@ ** */ +// HEADER FILES ------------------------------------------------------------ + +// MACROS ------------------------------------------------------------------ + +// TYPES ------------------------------------------------------------------- + +// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + +// CODE -------------------------------------------------------------------- + +//========================================================================== +// +// +// +//========================================================================== diff --git a/src/name.cpp b/src/name.cpp index db79902987..b8a7d123e9 100644 --- a/src/name.cpp +++ b/src/name.cpp @@ -3,7 +3,7 @@ ** Implements int-as-string mapping. ** **--------------------------------------------------------------------------- -** Copyright 2005-2006 Randy Heit +** Copyright 2005-2007 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -42,10 +42,10 @@ // 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 +#define BLOCK_SIZE 4096 // How many entries to grow the NameArray by when it needs to grow. -#define NAME_GROW_AMOUNT 48 +#define NAME_GROW_AMOUNT 256 // TYPES ------------------------------------------------------------------- @@ -125,7 +125,7 @@ int FName::NameManager::FindName (const char *text, bool noCreate) //========================================================================== // // The same as above, but the text length is also passed, for creating -// a name from a substring. +// a name from a substring or for speed if the length is already known. // //========================================================================== diff --git a/src/name.h b/src/name.h index 161ae5dfe4..fa161ab2e8 100644 --- a/src/name.h +++ b/src/name.h @@ -2,7 +2,7 @@ ** name.h ** **--------------------------------------------------------------------------- -** Copyright 2005-2006 Randy Heit +** Copyright 2005-2007 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -41,6 +41,8 @@ enum ENamedName #undef xx }; +class FString; + class FName { public: @@ -48,6 +50,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) { Index = other.Index; } FName (ENamedName index) { Index = index; } // ~FName () {} // Names can be added but never removed. @@ -58,6 +62,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) { Index = other.Index; return *this; } FName &operator = (ENamedName index) { Index = index; return *this; } @@ -98,7 +103,7 @@ protected: // means this struct must only exist in the program's BSS section. ~NameManager(); - enum { HASH_SIZE = 256 }; + enum { HASH_SIZE = 1024 }; struct NameBlock; NameBlock *Blocks; @@ -126,6 +131,7 @@ public: FNameNoInit() : FName(NoInit) {} FName &operator = (const char *text) { Index = NameData.FindName (text, false); return *this; } + FName &operator = (const FString &text); FName &operator = (const FName &other) { Index = int(other); return *this; } FName &operator = (ENamedName index) { Index = index; return *this; } }; diff --git a/src/version.h b/src/version.h index 5467d0adc7..897a13aa95 100644 --- a/src/version.h +++ b/src/version.h @@ -2,7 +2,7 @@ ** version.h ** **--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit +** Copyright 1998-2007 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -40,13 +40,13 @@ /** Lots of different version numbers **/ -#define DOTVERSIONSTR_NOREV "2.1.7" +#define DOTVERSIONSTR_NOREV "2.1.8" // The version string the user actually sees. #define DOTVERSIONSTR DOTVERSIONSTR_NOREV " (r" SVN_REVISION_STRING ")" // The version as seen in the Windows resource -#define RC_FILEVERSION 2,1,7,SVN_REVISION_NUMBER +#define RC_FILEVERSION 2,1,8,SVN_REVISION_NUMBER #define RC_PRODUCTVERSION 2,1,0,0 #define RC_FILEVERSION2 DOTVERSIONSTR #define RC_PRODUCTVERSION2 "2.1" @@ -73,8 +73,8 @@ // SAVEVER is the version of the information stored in level snapshots. // Note that SAVEVER is not directly comparable to VERSION. // SAVESIG should match SAVEVER. -#define SAVEVER 236 -#define SAVESIG "ZDOOMSAVE236" +#define SAVEVER 237 +#define SAVESIG "ZDOOMSAVE237" // This is so that derivates can use the same savegame versions without worrying about engine compatibility #define GAMESIG "ZDOOM" @@ -89,7 +89,7 @@ #endif // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 236 // Used by 2.1.7 +#define MINSAVEVER 237 // Used by 2.1.8 // The maximum length of one save game description for the menus. #define SAVESTRINGSIZE 24 diff --git a/src/win32/zdoom.rc b/src/win32/zdoom.rc index 049217edf0..94d11e0bbb 100644 --- a/src/win32/zdoom.rc +++ b/src/win32/zdoom.rc @@ -35,7 +35,7 @@ END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" - "#include ""../version.h""\0" + "#include ""../version.h\0" END 3 TEXTINCLUDE @@ -71,7 +71,7 @@ BEGIN " VALUE ""FileDescription"", ""ZDoom""\r\n" " VALUE ""FileVersion"", RC_FILEVERSION2\r\n" " VALUE ""InternalName"", ""ZDoom""\r\n" - " VALUE ""LegalCopyright"", ""Copyright © 1993-1996, id Software & 1998-2006, Randy Heit""\r\n" + " VALUE ""LegalCopyright"", ""Copyright © 1993-1996 id Software, 1998-2007 Randy Heit""\r\n" " VALUE ""LegalTrademarks"", ""Doom® is a Registered Trademark of id Software, Inc.""\r\n" " VALUE ""OriginalFilename"", ""zdoom.exe""\r\n" " VALUE ""ProductName"", ""ZDoom""\r\n" @@ -82,7 +82,7 @@ BEGIN " BEGIN\r\n" " VALUE ""Translation"", 0x409, 1200\r\n" " END\r\n" - "END\r\0" + "END\0" END #endif // APSTUDIO_INVOKED @@ -497,7 +497,7 @@ BEGIN VALUE "FileDescription", "ZDoom" VALUE "FileVersion", RC_FILEVERSION2 VALUE "InternalName", "ZDoom" - VALUE "LegalCopyright", "Copyright © 1993-1996, id Software & 1998-2006, Randy Heit" + VALUE "LegalCopyright", "Copyright © 1993-1996 id Software, 1998-2007 Randy Heit" VALUE "LegalTrademarks", "Doom® is a Registered Trademark of id Software, Inc." VALUE "OriginalFilename", "zdoom.exe" VALUE "ProductName", "ZDoom" diff --git a/src/zstring.cpp b/src/zstring.cpp index 26d3c201be..b744809383 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -1,3 +1,37 @@ +/* +** zstring.cpp +** A dynamically-allocated string class. +** +**--------------------------------------------------------------------------- +** Copyright 2005-2007 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 #include #include diff --git a/src/zstring.h b/src/zstring.h index ed51a73b5d..4d64261c62 100644 --- a/src/zstring.h +++ b/src/zstring.h @@ -1,3 +1,36 @@ +/* +** zstring.h +** +**--------------------------------------------------------------------------- +** Copyright 2005-2007 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 ZSTRING_H #define ZSTRING_H @@ -257,4 +290,12 @@ namespace StringFormat #undef PRINTFISH +// FName inline implementations that take FString parameters + +inline FName::FName(const FString &text) { Index = NameData.FindName (text, text.Len(), false); } +inline FName::FName(const FString &text, bool noCreate) { Index = NameData.FindName (text, text.Len(), noCreate); } +inline FName &FName::operator = (const FString &text) { Index = NameData.FindName (text, text.Len(), false); return *this; } +inline FName &FNameNoInit::operator = (const FString &text) { Index = NameData.FindName (text, text.Len(), false); return *this; } + + #endif