Clean up/refactor a few gamevar related functions based on building as C++/C99 and some interesting articles I read about how GCC and Clang optimize switches. Worth a few FPS here.

git-svn-id: https://svn.eduke32.com/eduke32@4895 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2015-01-11 04:53:44 +00:00
parent 67d30a18da
commit 1f2705c4bc
2 changed files with 123 additions and 137 deletions

View file

@ -573,48 +573,50 @@ static int32_t Gv_GetVarIndex(const char *szGameLabel)
int32_t __fastcall Gv_GetVar(int32_t id, int32_t iActor, int32_t iPlayer) int32_t __fastcall Gv_GetVar(int32_t id, int32_t iActor, int32_t iPlayer)
{ {
int negateResult;
if (id == g_iThisActorID) if (id == g_iThisActorID)
return iActor; return iActor;
if (id == MAXGAMEVARS) if (id == MAXGAMEVARS)
return(*insptr++); return *insptr++;
negateResult = id&(MAXGAMEVARS<<1); int negateResult = !!(id & (MAXGAMEVARS << 1));
if (EDUKE32_PREDICT_FALSE(id >= g_gameVarCount && !negateResult)) if (EDUKE32_PREDICT_FALSE(id >= g_gameVarCount && !negateResult))
goto nastyhacks; goto nastyhacks;
id &= (MAXGAMEVARS-1); id &= (MAXGAMEVARS - 1);
switch (aGameVars[id].dwFlags & int rv, f;
(GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK)) f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK);
if (!f) rv = (aGameVars[id].val.lValue ^ -negateResult) + negateResult;
else if (f == GAMEVAR_PERPLAYER)
{ {
default:
return ((aGameVars[id].val.lValue ^ -negateResult) + negateResult);
case GAMEVAR_PERPLAYER:
if (EDUKE32_PREDICT_FALSE((unsigned) iPlayer >= MAXPLAYERS)) goto bad_id; if (EDUKE32_PREDICT_FALSE((unsigned) iPlayer >= MAXPLAYERS)) goto bad_id;
return ((aGameVars[id].val.plValues[iPlayer] ^ -negateResult) + negateResult); rv = (aGameVars[id].val.plValues[iPlayer] ^ -negateResult) + negateResult;
case GAMEVAR_PERACTOR: }
else if (f == GAMEVAR_PERACTOR)
{
if (EDUKE32_PREDICT_FALSE((unsigned) iActor >= MAXSPRITES)) goto bad_id; if (EDUKE32_PREDICT_FALSE((unsigned) iActor >= MAXSPRITES)) goto bad_id;
return ((aGameVars[id].val.plValues[iActor] ^ -negateResult) + negateResult); rv = (aGameVars[id].val.plValues[iActor] ^ -negateResult) + negateResult;
case GAMEVAR_INTPTR: }
return (((*((int32_t *) aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); else switch (f)
case GAMEVAR_SHORTPTR: {
return (((*((int16_t *) aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); case GAMEVAR_INTPTR: rv = ((*((int32_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult; break;
case GAMEVAR_CHARPTR: case GAMEVAR_SHORTPTR: rv = ((*((int16_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult; break;
return (((*((char *) aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); case GAMEVAR_CHARPTR: rv = ((*((char *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult; break;
} }
return rv;
nastyhacks: nastyhacks:
if (id&(MAXGAMEVARS<<2)) // array if (id & (MAXGAMEVARS << 2)) // array
{ {
int32_t index=Gv_GetVar(*insptr++, iActor, iPlayer); id &= (MAXGAMEVARS - 1); // ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1));
id &= (MAXGAMEVARS-1);// ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1)); int32_t index = Gv_GetVar(*insptr++, iActor, iPlayer);
if (EDUKE32_PREDICT_FALSE((unsigned) index >= (unsigned) aGameArrays[id].size)) if (EDUKE32_PREDICT_FALSE((unsigned)index >= (unsigned)aGameArrays[id].size))
{ {
iActor = index; iActor = index;
goto badindex; goto badindex;
@ -719,33 +721,31 @@ void __fastcall Gv_SetVar(int32_t id, int32_t lValue, int32_t iActor, int32_t iP
{ {
if (EDUKE32_PREDICT_FALSE((unsigned)id >= (unsigned)g_gameVarCount)) goto badvarid; if (EDUKE32_PREDICT_FALSE((unsigned)id >= (unsigned)g_gameVarCount)) goto badvarid;
//Bsprintf(g_szBuf,"SGVI: %d (\"%s\") to %d for %d %d",id,aGameVars[id].szLabel,lValue,iActor,iPlayer); int f;
//AddLog(g_szBuf); f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK)) if (!f) aGameVars[id].val.lValue=lValue;
else if (f == GAMEVAR_PERPLAYER)
{ {
default: if (EDUKE32_PREDICT_FALSE((unsigned) iPlayer > MAXPLAYERS-1)) goto badindex;
aGameVars[id].val.lValue=lValue;
return;
case GAMEVAR_PERPLAYER:
if (EDUKE32_PREDICT_FALSE((unsigned)iPlayer > MAXPLAYERS-1)) goto badindex;
// for the current player // for the current player
aGameVars[id].val.plValues[iPlayer]=lValue; aGameVars[id].val.plValues[iPlayer]=lValue;
return;
case GAMEVAR_PERACTOR:
if (EDUKE32_PREDICT_FALSE((unsigned)iActor > MAXSPRITES-1)) goto badindex;
aGameVars[id].val.plValues[iActor]=lValue;
return;
case GAMEVAR_INTPTR:
*((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue;
return;
case GAMEVAR_SHORTPTR:
*((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue;
return;
case GAMEVAR_CHARPTR:
*((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
return;
} }
else if (f == GAMEVAR_PERACTOR)
{
if (EDUKE32_PREDICT_FALSE((unsigned) iActor > MAXSPRITES-1)) goto badindex;
aGameVars[id].val.plValues[iActor]=lValue;
}
else
{
switch (f)
{
case GAMEVAR_INTPTR: *((int32_t *)aGameVars[id].val.lValue) = (int32_t)lValue; break;
case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[id].val.lValue) = (int16_t)lValue; break;
case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[id].val.lValue) = (uint8_t)lValue; break;
}
}
return;
badvarid: badvarid:
CON_ERRPRINTF("Gv_SetVar(): invalid gamevar (%d) from sprite %d (%d), player %d\n", CON_ERRPRINTF("Gv_SetVar(): invalid gamevar (%d) from sprite %d (%d), player %d\n",
@ -756,7 +756,6 @@ badindex:
CON_ERRPRINTF("Gv_SetVar(): invalid index (%d) for gamevar %s from sprite %d, player %d\n", CON_ERRPRINTF("Gv_SetVar(): invalid index (%d) for gamevar %s from sprite %d, player %d\n",
aGameVars[id].dwFlags & GAMEVAR_PERACTOR ? iActor : iPlayer, aGameVars[id].dwFlags & GAMEVAR_PERACTOR ? iActor : iPlayer,
aGameVars[id].szLabel,vm.g_i,vm.g_p); aGameVars[id].szLabel,vm.g_i,vm.g_p);
return;
} }
enum { enum {
@ -768,62 +767,68 @@ enum {
GVX_BADINDEX, GVX_BADINDEX,
}; };
static const char *gvxerrs [] ={ "Gv_GetVarX(): invalid gamevar ID", static const char *gvxerrs[] = {
"Gv_GetVarX(): invalid player ID", "Gv_GetVarX(): invalid gamevar ID",
"Gv_GetVarX(): invalid sprite ID", "Gv_GetVarX(): invalid player ID",
"Gv_GetVarX(): invalid sector ID", "Gv_GetVarX(): invalid sprite ID",
"Gv_GetVarX(): invalid wall ID", "Gv_GetVarX(): invalid sector ID",
"Gv_GetVarX(): invalid array index", "Gv_GetVarX(): invalid wall ID",
"Gv_GetVarX(): invalid array index",
}; };
int32_t __fastcall Gv_GetVarX(int32_t id) int32_t __fastcall Gv_GetVarX(int32_t id)
{ {
intptr_t negateResult = id&(MAXGAMEVARS<<1);
if (id == g_iThisActorID) if (id == g_iThisActorID)
return vm.g_i; return vm.g_i;
if (id == MAXGAMEVARS) if (id == MAXGAMEVARS)
return(*insptr++); return *insptr++;
int negateResult = !!(id & (MAXGAMEVARS << 1)), rv = -1, f;
if (EDUKE32_PREDICT_FALSE(id >= g_gameVarCount && negateResult == 0)) if (EDUKE32_PREDICT_FALSE(id >= g_gameVarCount && negateResult == 0))
goto nastyhacks; goto nastyhacks;
id &= MAXGAMEVARS-1; id &= MAXGAMEVARS-1;
switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK)) f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
if (!f) rv = (aGameVars[id].val.lValue ^ -negateResult) + negateResult;
else if (f == GAMEVAR_PERPLAYER)
{ {
default:
return ((aGameVars[id].val.lValue ^ -negateResult) + negateResult);
case GAMEVAR_PERPLAYER:
if (EDUKE32_PREDICT_FALSE((unsigned) vm.g_p >= MAXPLAYERS)) if (EDUKE32_PREDICT_FALSE((unsigned) vm.g_p >= MAXPLAYERS))
{ goto perr;
id = vm.g_p; rv = (aGameVars[id].val.plValues[vm.g_p] ^ -negateResult) + negateResult;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], id); }
return -1; else if (f == GAMEVAR_PERACTOR)
} rv = (aGameVars[id].val.plValues[vm.g_i] ^ -negateResult) + negateResult;
return ((aGameVars[id].val.plValues[vm.g_p] ^ -negateResult) + negateResult); else switch (f)
case GAMEVAR_PERACTOR: {
return ((aGameVars[id].val.plValues[vm.g_i] ^ -negateResult) + negateResult); case GAMEVAR_INTPTR:
case GAMEVAR_INTPTR: rv = ((*((int32_t *) aGameVars[id].val.lValue)) ^ -negateResult) + negateResult; break;
return (((*((int32_t *) aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); case GAMEVAR_SHORTPTR:
case GAMEVAR_SHORTPTR: rv = ((*((int16_t *) aGameVars[id].val.lValue)) ^ -negateResult) + negateResult; break;
return (((*((int16_t *) aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); case GAMEVAR_CHARPTR:
case GAMEVAR_CHARPTR: rv = ((*((uint8_t *) aGameVars[id].val.lValue)) ^ -negateResult) + negateResult; break;
return (((*((uint8_t *) aGameVars[id].val.lValue)) ^ -negateResult) + negateResult);
} }
return rv;
perr:
id = vm.g_p;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], id);
return -1;
nastyhacks: nastyhacks:
if (id&(MAXGAMEVARS<<2)) // array if (id & (MAXGAMEVARS << 2)) // array
{ {
int32_t index=Gv_GetVarX(*insptr++); int32_t index = Gv_GetVarX(*insptr++);
int32_t siz;
id &= (MAXGAMEVARS-1);// ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1)); id &= (MAXGAMEVARS - 1); // ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1));
siz = (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(aGameArrays[id].size) : aGameArrays[id].size; int siz = (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(aGameArrays[id].size) : aGameArrays[id].size;
if (EDUKE32_PREDICT_FALSE(index < 0 || index >= siz)) if (EDUKE32_PREDICT_FALSE((unsigned) index >= (unsigned) siz))
{ {
negateResult = index; negateResult = index;
CON_ERRPRINTF("%s %s[%d]\n", gvxerrs[GVX_BADINDEX], aGameArrays[id].szLabel, index); CON_ERRPRINTF("%s %s[%d]\n", gvxerrs[GVX_BADINDEX], aGameArrays[id].szLabel, index);
@ -832,16 +837,12 @@ nastyhacks:
switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK) switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK)
{ {
case 0: case 0: return ((aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult;
return ((aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult; case GAMEARRAY_OFINT: return (((int32_t *) aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult;
case GAMEARRAY_OFINT: case GAMEARRAY_OFSHORT:
return (((int32_t *) aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult; return (((int16_t *) aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult;
case GAMEARRAY_OFSHORT: case GAMEARRAY_OFCHAR: return (((uint8_t *) aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult;
return (((int16_t *) aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult; default: EDUKE32_UNREACHABLE_SECTION(return -1);
case GAMEARRAY_OFCHAR:
return (((uint8_t *) aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult;
default:
EDUKE32_UNREACHABLE_SECTION(return -1);
} }
} }
@ -916,35 +917,35 @@ nastyhacks:
void __fastcall Gv_SetVarX(int32_t id, int32_t lValue) void __fastcall Gv_SetVarX(int32_t id, int32_t lValue)
{ {
switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK)) int f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
if (!f) aGameVars[id].val.lValue = lValue;
else if (f == GAMEVAR_PERPLAYER)
{ {
default: if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p >= MAXPLAYERS)) goto badindex;
aGameVars[id].val.lValue=lValue; aGameVars[id].val.plValues[vm.g_p] = lValue;
return;
case GAMEVAR_PERPLAYER:
if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p > MAXPLAYERS-1)) goto badindex;
aGameVars[id].val.plValues[vm.g_p]=lValue;
return;
case GAMEVAR_PERACTOR:
if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_i > MAXSPRITES-1)) goto badindex;
aGameVars[id].val.plValues[vm.g_i]=lValue;
return;
case GAMEVAR_INTPTR:
*((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue;
return;
case GAMEVAR_SHORTPTR:
*((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue;
return;
case GAMEVAR_CHARPTR:
*((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
return;
} }
else if (f == GAMEVAR_PERACTOR)
{
if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_i >= MAXSPRITES)) goto badindex;
aGameVars[id].val.plValues[vm.g_i] = lValue;
}
else
{
switch (f)
{
case GAMEVAR_INTPTR: *((int32_t *)aGameVars[id].val.lValue) = (int32_t)lValue; break;
case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[id].val.lValue) = (int16_t)lValue; break;
case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[id].val.lValue) = (uint8_t)lValue; break;
}
}
return;
badindex: badindex:
CON_ERRPRINTF("Gv_SetVar(): invalid index (%d) for gamevar %s\n", CON_ERRPRINTF("Gv_SetVar(): invalid index (%d) for gamevar %s\n",
aGameVars[id].dwFlags & GAMEVAR_PERACTOR ? vm.g_i : vm.g_p, aGameVars[id].dwFlags & GAMEVAR_PERACTOR ? vm.g_i : vm.g_p,
aGameVars[id].szLabel); aGameVars[id].szLabel);
return;
} }
int32_t Gv_GetVarByLabel(const char *szGameLabel, int32_t lDefault, int32_t iActor, int32_t iPlayer) int32_t Gv_GetVarByLabel(const char *szGameLabel, int32_t lDefault, int32_t iActor, int32_t iPlayer)
@ -972,13 +973,6 @@ static intptr_t *Gv_GetVarDataPtr(const char *szGameLabel)
} }
#endif // !defined LUNATIC #endif // !defined LUNATIC
static void G_InitProjectileData(void)
{
int32_t i;
for (i=0; i<=MAXTILES-1; i++)
Bmemcpy(&ProjectileData[i], &g_tile[i].defproj, sizeof(projectile_t));
}
void Gv_ResetSystemDefaults(void) void Gv_ResetSystemDefaults(void)
{ {
// call many times... // call many times...
@ -1053,25 +1047,21 @@ void Gv_ResetSystemDefaults(void)
g_iPlayerVarID=Gv_GetVarIndex("player"); g_iPlayerVarID=Gv_GetVarIndex("player");
g_iActorVarID=Gv_GetVarIndex("actorvar"); g_iActorVarID=Gv_GetVarIndex("actorvar");
#endif #endif
G_InitProjectileData();
for (i = 0; i <= MAXTILES - 1; i++)
Bmemcpy(&ProjectileData[i], &g_tile[i].defproj, sizeof(projectile_t));
#ifndef LUNATIC #ifndef LUNATIC
// hackhackhackhackhack // hackhackhackhackhack
i = hash_find(&h_arrays, "tilesizx"); if (i = hash_find(&h_arrays, "tilesizx"), i >= 0)
if (i >= 0)
{ {
int32_t j = 0; for (int j = 0; j < MAXTILES; j++)
for (; j<MAXTILES; j++)
aGameArrays[i].plValues[j] = tilesiz[j].x; aGameArrays[i].plValues[j] = tilesiz[j].x;
} }
i = hash_find(&h_arrays, "tilesizy"); if (i = hash_find(&h_arrays, "tilesizy"), i >= 0)
if (i >= 0)
{ {
int32_t j = 0; for (int j = 0; j < MAXTILES; j++)
for (; j<MAXTILES; j++)
aGameArrays[i].plValues[j] = tilesiz[j].y; aGameArrays[i].plValues[j] = tilesiz[j].y;
} }
#endif #endif
@ -1199,6 +1189,7 @@ static int32_t G_StaticToDynamicTile(int32_t tile)
default: return tile; default: return tile;
} }
} }
static int32_t G_StaticToDynamicSound(int32_t sound) static int32_t G_StaticToDynamicSound(int32_t sound)
{ {
switch (sound) switch (sound)
@ -1469,13 +1460,9 @@ static void Gv_AddSystemVars(void)
void Gv_Init(void) void Gv_Init(void)
{ {
// only call ONCE // already initialized
if (aGameVars[0].dwFlags)
// (... not true anymore)
static int32_t inited=0;
if (inited)
return; return;
inited = 1;
#if !defined LUNATIC #if !defined LUNATIC
Gv_Clear(); Gv_Clear();

View file

@ -111,8 +111,7 @@ int32_t Gv_NewVar(const char *pszLabel,intptr_t lValue,uint32_t dwFlags);
static inline void A_ResetVars(const int32_t iActor) static inline void A_ResetVars(const int32_t iActor)
{ {
int i; for (int i = 0; i < g_gameVarCount; i++)
for (i = 0; i < g_gameVarCount; i++)
{ {
if ((aGameVars[i].dwFlags & (GAMEVAR_PERACTOR | GAMEVAR_NODEFAULT)) == GAMEVAR_PERACTOR) if ((aGameVars[i].dwFlags & (GAMEVAR_PERACTOR | GAMEVAR_NODEFAULT)) == GAMEVAR_PERACTOR)
aGameVars[i].val.plValues[iActor] = aGameVars[i].lDefault; aGameVars[i].val.plValues[iActor] = aGameVars[i].lDefault;