Skin name search-assistive hashing

More opportunities for early rejection in table-wide searches, in anticipation of future work.
- Many circumstances independently implemented string name comparisons. Most of these have been converted to use R_SkinAvailable, with one exception.
    - M_CharacterSelectInit already needs to iterate over the characters, so produce the skin hash independently.
This commit is contained in:
toaster 2023-05-27 19:08:14 +01:00
parent 0f266198ca
commit 8d9b42e49b
8 changed files with 56 additions and 45 deletions

View file

@ -264,16 +264,12 @@ static bool ACS_GetStateFromString(const char *word, statenum_t *type)
--------------------------------------------------*/ --------------------------------------------------*/
static bool ACS_GetSkinFromString(const char *word, INT32 *type) static bool ACS_GetSkinFromString(const char *word, INT32 *type)
{ {
for (int i = 0; i < numskins; i++) INT32 skin = R_SkinAvailable(word);
{ if (skin == -1)
if (fastcmp(word, skins[i].name)) return false;
{
*type = i;
return true;
}
}
return false; *type = skin;
return true;
} }
/*-------------------------------------------------- /*--------------------------------------------------

View file

@ -570,17 +570,15 @@ void HWR_InitModels(void)
addskinmodel: addskinmodel:
// add player model // add player model
for (s = 0; s < MAXSKINS; s++) s = R_SkinAvailable(skinname);
if (s != -1)
{ {
if (stricmp(skinname, skins[s].name) == 0) md2_playermodels[s].skin = s;
{ md2_playermodels[s].scale = scale;
md2_playermodels[s].skin = s; md2_playermodels[s].offset = offset;
md2_playermodels[s].scale = scale; md2_playermodels[s].notfound = false;
md2_playermodels[s].offset = offset; strcpy(md2_playermodels[s].filename, filename);
md2_playermodels[s].notfound = false; goto modelfound;
strcpy(md2_playermodels[s].filename, filename);
goto modelfound;
}
} }
// no sprite/player skin name found?!?D // no sprite/player skin name found?!?D

View file

@ -386,10 +386,8 @@ static int libd_getSprite2Patch(lua_State *L)
else // find skin by name else // find skin by name
{ {
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
for (i = 0; i < numskins; i++) i = R_SkinAvailable(name);
if (fastcmp(skins[i].name, name)) if (i == -1)
break;
if (i >= numskins)
return 0; return 0;
} }

View file

@ -662,17 +662,16 @@ static int mobj_set(lua_State *L)
break; break;
case mobj_skin: // set skin by name case mobj_skin: // set skin by name
{ {
INT32 i; const char *name = luaL_checkstring(L, 3);
char skin[SKINNAMESIZE+1]; // all skin names are limited to this length INT32 skin = R_SkinAvailable(name);
strlcpy(skin, luaL_checkstring(L, 3), sizeof skin);
strlwr(skin); // all skin names are lowercase if (skin != -1)
for (i = 0; i < numskins; i++) {
if (fastcmp(skins[i].name, skin)) if (!mo->player || R_SkinUsable(mo->player-players, skin, false))
{ mo->skin = &skins[skin];
if (!mo->player || R_SkinUsable(mo->player-players, i, false))
mo->skin = &skins[i]; return 0;
return 0; }
}
return luaL_error(L, "mobj.skin '%s' not found!", skin); return luaL_error(L, "mobj.skin '%s' not found!", skin);
} }
case mobj_color: case mobj_color:

View file

@ -196,12 +196,12 @@ static int lib_getSkin(lua_State *L)
} }
// find skin by name // find skin by name
for (i = 0; i < numskins; i++) i = R_SkinAvailable(field);
if (fastcmp(skins[i].name, field)) if (i != -1)
{ {
LUA_PushUserdata(L, &skins[i], META_SKIN); LUA_PushUserdata(L, &skins[i], META_SKIN);
return 1; return 1;
} }
return 0; return 0;
} }

View file

@ -404,6 +404,8 @@ void M_CharacterSelectInit(void)
memset(setup_explosions, 0, sizeof(setup_explosions)); memset(setup_explosions, 0, sizeof(setup_explosions));
setup_animcounter = 0; setup_animcounter = 0;
UINT32 localskinhash[MAXSPLITSCREENPLAYERS];
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{ {
// Default to no follower / match colour. // Default to no follower / match colour.
@ -414,6 +416,9 @@ void M_CharacterSelectInit(void)
// Set default selected profile to the last used profile for each player: // Set default selected profile to the last used profile for each player:
// (Make sure we don't overshoot it somehow if we deleted profiles or whatnot) // (Make sure we don't overshoot it somehow if we deleted profiles or whatnot)
setup_player[i].profilen = min(cv_lastprofile[i].value, PR_GetNumProfiles()); setup_player[i].profilen = min(cv_lastprofile[i].value, PR_GetNumProfiles());
// Assistant for comparisons.
localskinhash[i] = quickncasehash(cv_skin[i].string, SKINNAMESIZE);
} }
for (i = 0; i < numskins; i++) for (i = 0; i < numskins; i++)
@ -436,7 +441,14 @@ void M_CharacterSelectInit(void)
for (j = 0; j < MAXSPLITSCREENPLAYERS; j++) for (j = 0; j < MAXSPLITSCREENPLAYERS; j++)
{ {
if (!strcmp(cv_skin[j].string, skins[i].name)) // See also R_SkinAvailable
if (localskinhash[j] != skins[i].namehash)
continue;
if (!stricmp(cv_skin[j].string, skins[i].name))
continue;
{ {
setup_player[j].gridx = x; setup_player[j].gridx = x;
setup_player[j].gridy = y; setup_player[j].gridy = y;

View file

@ -314,12 +314,17 @@ UINT32 R_GetLocalRandomSkin(void)
INT32 R_SkinAvailable(const char *name) INT32 R_SkinAvailable(const char *name)
{ {
INT32 i; INT32 i;
UINT32 hash = quickncasehash(name, SKINNAMESIZE);
for (i = 0; i < numskins; i++) for (i = 0; i < numskins; i++)
{ {
// search in the skin list if (skins[i].namehash != hash)
if (stricmp(skins[i].name,name)==0) continue;
return i;
if (stricmp(skins[i].name,name)!=0)
continue;
return i;
} }
return -1; return -1;
} }
@ -954,6 +959,8 @@ void R_AddSkins(UINT16 wadnum, boolean mainfile)
Z_Free(value2); Z_Free(value2);
} }
skin->namehash = quickncasehash(skin->name, SKINNAMESIZE);
// copy to hudname and fullname as a default. // copy to hudname and fullname as a default.
if (!realname) if (!realname)
{ {

View file

@ -37,7 +37,8 @@ extern "C" {
/// The skin_t struct /// The skin_t struct
struct skin_t struct skin_t
{ {
char name[SKINNAMESIZE+1]; // INT16 descriptive name of the skin char name[SKINNAMESIZE+1]; // descriptive name of the skin
UINT32 namehash; // quickncasehash(->name, SKINNAMESIZE)
UINT16 wadnum; UINT16 wadnum;
skinflags_t flags; skinflags_t flags;