diff --git a/src/deh_soc.c b/src/deh_soc.c index 751c3c07a..2bd662828 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -953,6 +953,7 @@ void readlevelheader(MYFILE *f, char * name) if (mapheaderinfo[num]->lumpname == NULL) { mapheaderinfo[num]->lumpname = Z_StrDup(name); + mapheaderinfo[num]->lumpnamehash = quickncasehash(mapheaderinfo[num]->lumpname, MAXMAPLUMPNAME); } do @@ -2638,9 +2639,10 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) ty = UCRP_PODIUMCUP; { cupheader_t *cup = kartcupheaders; + UINT32 hash = quickncasehash(params[1], MAXCUPNAME); while (cup) { - if (!strcmp(cup->name, params[1])) + if (hash == cup->namehash && !strcmp(cup->name, params[1])) break; cup = cup->next; } diff --git a/src/dehacked.c b/src/dehacked.c index 9e50a9f42..ea35a07e5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -465,39 +465,51 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) // else if (fastcmp(word, "CUP")) { - cupheader_t *cup = kartcupheaders; - cupheader_t *prev = NULL; - - while (cup) + size_t len = strlen(word2); + if (len <= MAXCUPNAME-1) { - if (fastcmp(cup->name, word2)) + cupheader_t *cup = kartcupheaders; + cupheader_t *prev = NULL; + UINT32 hash = quickncasehash(word2, MAXCUPNAME); + + while (cup) { - // Only a major mod if editing stuff that isn't your own! - G_SetGameModified(multiplayer, true); - break; + if (hash == cup->namehash && fastcmp(cup->name, word2)) + { + // Only a major mod if editing stuff that isn't your own! + G_SetGameModified(multiplayer, true); + break; + } + + prev = cup; + cup = cup->next; } - prev = cup; - cup = cup->next; - } + // Nothing found, add to the end. + if (!cup) + { + cup = Z_Calloc(sizeof (cupheader_t), PU_STATIC, NULL); + cup->id = numkartcupheaders; + cup->monitor = 1; + deh_strlcpy(cup->name, word2, + sizeof(cup->name), va("Cup header %s: name", word2)); + cup->namehash = hash; + if (prev != NULL) + prev->next = cup; + if (kartcupheaders == NULL) + kartcupheaders = cup; + numkartcupheaders++; + CONS_Printf("Added cup %d ('%s')\n", cup->id, cup->name); + } - // Nothing found, add to the end. - if (!cup) + readcupheader(f, cup); + + } + else { - cup = Z_Calloc(sizeof (cupheader_t), PU_STATIC, NULL); - cup->id = numkartcupheaders; - cup->monitor = 1; - deh_strlcpy(cup->name, word2, - sizeof(cup->name), va("Cup header %s: name", word2)); - if (prev != NULL) - prev->next = cup; - if (kartcupheaders == NULL) - kartcupheaders = cup; - numkartcupheaders++; - CONS_Printf("Added cup %d ('%s')\n", cup->id, cup->name); + deh_warning("Cup header's name %s is too long (%s characters VS %d max)", word2, sizeu1(len), (MAXCUPNAME-1)); + ignorelines(f); } - - readcupheader(f, cup); } else if (fastcmp(word, "WEATHER") || fastcmp(word, "PRECIP") || fastcmp(word, "PRECIPITATION")) { diff --git a/src/doomstat.h b/src/doomstat.h index 77317fd0a..ab73c70dc 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -363,11 +363,16 @@ struct customoption_t #define CUPCACHE_SPECIAL (CUPCACHE_BONUS+MAXBONUSLIST) #define CUPCACHE_MAX (CUPCACHE_SPECIAL+1) +#define MAXCUPNAME 16 // includes \0, for cleaner savedata + struct cupheader_t { UINT16 id; ///< Cup ID UINT8 monitor; ///< Monitor graphic 1-9 or A-Z - char name[15]; ///< Cup title (14 chars) + + char name[MAXCUPNAME]; ///< Cup title + UINT32 namehash; ///< Cup title hash + char icon[9]; ///< Name of the icon patch char *levellist[CUPCACHE_MAX]; ///< List of levels that belong to this cup INT16 cachedlevels[CUPCACHE_MAX]; ///< IDs in levellist, bonusgame, and specialstage @@ -400,6 +405,7 @@ struct mapheader_t { // Core game information, not user-modifiable directly char *lumpname; ///< Lump name can be really long + UINT32 lumpnamehash; ///< quickncasehash(->lumpname, MAXMAPLUMPNAME) lumpnum_t lumpnum; ///< Lump number for the map, used by vres_GetMap void *thumbnailPic; ///< Lump data for the level select thumbnail. diff --git a/src/g_game.c b/src/g_game.c index 9f75d137a..cf2e4b184 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -807,9 +807,13 @@ INT32 G_MapNumber(const char * name) #endif { INT32 map; + UINT32 hash = quickncasehash(name, MAXMAPLUMPNAME); for (map = 0; map < nummapheaders; ++map) { + if (hash != mapheaderinfo[map]->lumpnamehash) + continue; + if (strcasecmp(mapheaderinfo[map]->lumpname, name) != 0) continue; @@ -4980,15 +4984,20 @@ void G_LoadGameData(void) for (i = 0; i < numgamedatacups; i++) { - char cupname[16]; + char cupname[MAXCUPNAME]; cupheader_t *cup; // Find the relevant cup. READSTRINGN(save.p, cupname, sizeof(cupname)); + UINT32 hash = quickncasehash(cupname, MAXCUPNAME); for (cup = kartcupheaders; cup; cup = cup->next) { + if (cup->namehash != hash) + continue; + if (strcmp(cup->name, cupname)) continue; + break; } diff --git a/src/m_cond.c b/src/m_cond.c index 5b551f646..41510210c 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -2064,9 +2064,10 @@ cupheader_t *M_UnlockableCup(unlockable_t *unlock) if (unlock->stringVarCache == -1) { // Get the cup from the string. + UINT32 hash = quickncasehash(unlock->stringVar, MAXCUPNAME); while (cup) { - if (!strcmp(cup->name, unlock->stringVar)) + if (hash == cup->namehash && !strcmp(cup->name, unlock->stringVar)) break; cup = cup->next; }