Add spr2defaults[] array to make sprite2 defaulting system much, much simpler to manage.

This is in preparation for a seperate project which still involves sprite2s.
This commit is contained in:
toasterbabe 2017-08-25 18:00:20 +01:00
parent c17eb94ef7
commit 4da6169892
6 changed files with 251 additions and 138 deletions

View File

@ -64,6 +64,7 @@ memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\
static mobjtype_t get_mobjtype(const char *word);
static statenum_t get_state(const char *word);
static spritenum_t get_sprite(const char *word);
static playersprite_t get_sprite2(const char *word);
static sfxenum_t get_sfx(const char *word);
#ifdef MUSICSLOT_COMPATIBILITY
static UINT16 get_mus(const char *word, UINT8 dehacked_mode);
@ -769,6 +770,49 @@ static void readspritelight(MYFILE *f, INT32 num)
}
#endif // HWRENDER
static void readsprite2(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word, *word2;
char *tmp;
do
{
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
if (s == tmp)
continue; // Skip comment lines, but don't break.
word = strtok(s, " ");
if (word)
strupr(word);
else
break;
word2 = strtok(NULL, " = ");
if (word2)
strupr(word2);
else
break;
if (word2[strlen(word2)-1] == '\n')
word2[strlen(word2)-1] = '\0';
if (fastcmp(word, "DEFAULT"))
spr2defaults[num] = get_number(word2);
else
deh_warning("Sprite2 %s: unknown word '%s'", spr2names[num], word);
}
} while (!myfeof(f)); // finish when the line is empty
Z_Free(s);
}
static const struct {
const char *name;
const UINT16 flag;
@ -3020,9 +3064,21 @@ static void DEH_LoadDehackedFile(MYFILE *f)
ignorelines(f);
}
}
else if (fastcmp(word, "SPRITE2"))
{
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_sprite2(word2); // find a sprite by name
if (i < (INT32)free_spr2 && i >= (INT32)SPR2_FIRSTFREESLOT)
readsprite2(f, i);
else
{
deh_warning("Sprite2 number %d out of range (%d - %d)", i, SPR2_FIRSTFREESLOT, free_spr2-1);
ignorelines(f);
}
}
#ifdef HWRENDER
else if (fastcmp(word, "LIGHT"))
{
#ifdef HWRENDER
// TODO: Read lights by name
if (i > 0 && i < NUMLIGHTS)
readlight(f, i);
@ -3031,22 +3087,20 @@ static void DEH_LoadDehackedFile(MYFILE *f)
deh_warning("Light number %d out of range (1 - %d)", i, NUMLIGHTS-1);
ignorelines(f);
}
#endif
}
else if (fastcmp(word, "SPRITE"))
{
#ifdef HWRENDER
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_sprite(word2); // find a sprite by name
if (i < NUMSPRITES && i >= 0)
if (i < NUMSPRITES && i > 0)
readspritelight(f, i);
else
{
deh_warning("Sprite number %d out of range (0 - %d)", i, NUMSPRITES-1);
ignorelines(f);
}
#endif
}
#endif
else if (fastcmp(word, "LEVEL"))
{
// Support using the actual map name,
@ -7290,6 +7344,20 @@ static spritenum_t get_sprite(const char *word)
return SPR_NULL;
}
static playersprite_t get_sprite2(const char *word)
{ // Returns the value of SPR2_ enumerations
playersprite_t i;
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("SPR2_",word,5))
word += 5; // take off the SPR2_
for (i = 0; i < NUMPLAYERSPRITES; i++)
if (!spr2names[i][4] && memcmp(word,spr2names[i],4)==0)
return i;
deh_warning("Couldn't find sprite named 'SPR2_%s'",word);
return SPR2_STND;
}
static sfxenum_t get_sfx(const char *word)
{ // Returns the value of SFX_ enumerations
sfxenum_t i;
@ -7735,7 +7803,7 @@ static inline int lib_freeslot(lua_State *L)
else if (fastcmp(type, "SPR2"))
{
// Search if we already have an SPR2 by that name...
enum playersprite i;
playersprite_t i;
for (i = SPR2_FIRSTFREESLOT; i < free_spr2; i++)
if (memcmp(spr2names[i],word,4) == 0)
break;

View File

@ -481,7 +481,88 @@ char spr2names[NUMPLAYERSPRITES][5] =
"SIGN",
"LIFE"
};
enum playersprite free_spr2 = SPR2_FIRSTFREESLOT;
playersprite_t free_spr2 = SPR2_FIRSTFREESLOT;
playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
0, // SPR2_STND,
0, // SPR2_WAIT,
0, // SPR2_WALK,
SPR2_WALK, // SPR2_RUN ,
SPR2_FRUN, // SPR2_DASH,
0, // SPR2_PAIN,
SPR2_PAIN, // SPR2_STUN,
0, // SPR2_DEAD,
SPR2_DEAD, // SPR2_DRWN,
0, // SPR2_ROLL,
SPR2_SPNG, // SPR2_GASP,
0, // SPR2_JUMP, (conditional)
SPR2_FALL, // SPR2_SPNG,
SPR2_WALK, // SPR2_FALL,
0, // SPR2_EDGE,
SPR2_FALL, // SPR2_RIDE,
SPR2_ROLL, // SPR2_SPIN,
SPR2_SPNG, // SPR2_FLY ,
SPR2_FLY , // SPR2_SWIM,
0, // SPR2_TIRE, (conditional)
SPR2_FLY , // SPR2_GLID,
SPR2_CLMB, // SPR2_CLNG,
SPR2_ROLL, // SPR2_CLMB,
SPR2_WALK, // SPR2_FLT ,
SPR2_RUN , // SPR2_FRUN,
SPR2_FALL, // SPR2_BNCE,
SPR2_ROLL, // SPR2_BLND,
0, // SPR2_FIRE,
SPR2_ROLL, // SPR2_TWIN,
SPR2_TWIN, // SPR2_MLEE,
0, // SPR2_MLEL,
0, // SPR2_TRNS,
0, // SPR2_NSTD,
0, // SPR2_NFLT,
0, // SPR2_NSTN,
SPR2_NSTN, // SPR2_NPUL,
0, // SPR2_NATK,
0, // SPR2_NGT0, (should never be referenced)
SPR2_NGT0, // SPR2_NGT1,
SPR2_NGT1, // SPR2_NGT2,
SPR2_NGT2, // SPR2_NGT3,
SPR2_NGT3, // SPR2_NGT4,
SPR2_NGT4, // SPR2_NGT5,
SPR2_NGT5, // SPR2_NGT6,
SPR2_NGT0, // SPR2_NGT7,
SPR2_NGT7, // SPR2_NGT8,
SPR2_NGT8, // SPR2_NGT9,
SPR2_NGT9, // SPR2_NGTA,
SPR2_NGTA, // SPR2_NGTB,
SPR2_NGTB, // SPR2_NGTC,
SPR2_NGT0, // SPR2_DRL0,
SPR2_NGT1, // SPR2_DRL1,
SPR2_NGT2, // SPR2_DRL2,
SPR2_NGT3, // SPR2_DRL3,
SPR2_NGT4, // SPR2_DRL4,
SPR2_NGT5, // SPR2_DRL5,
SPR2_NGT6, // SPR2_DRL6,
SPR2_NGT7, // SPR2_DRL7,
SPR2_NGT8, // SPR2_DRL8,
SPR2_NGT9, // SPR2_DRL9,
SPR2_NGTA, // SPR2_DRLA,
SPR2_NGTB, // SPR2_DRLB,
SPR2_NGTC, // SPR2_DRLC,
0, // SPR2_SIGN,
0, // SPR2_LIFE
};
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
state_t states[NUMSTATES] =

View File

@ -604,7 +604,7 @@ typedef enum sprite
// Make sure to be conscious of FF_FRAMEMASK and the fact sprite2 is stored as a UINT8 whenever you change this table.
// Currently, FF_FRAMEMASK is 0xff, or 255 - but the second half is used by FF_SPR2SUPER, so the limitation is 0x7f.
// Since this is zero-based, there can be at most 128 different SPR2_'s without changing that.
enum playersprite
typedef enum playersprite
{
SPR2_STND = 0,
SPR2_WAIT,
@ -690,7 +690,7 @@ enum playersprite
SPR2_FIRSTFREESLOT,
SPR2_LASTFREESLOT = 0x7f,
NUMPLAYERSPRITES
};
} playersprite_t;
typedef enum state
{
@ -3193,8 +3193,9 @@ typedef struct
extern state_t states[NUMSTATES];
extern char sprnames[NUMSPRITES + 1][5];
extern char spr2names[NUMPLAYERSPRITES][5];
extern playersprite_t spr2defaults[NUMPLAYERSPRITES];
extern state_t *astate;
extern enum playersprite free_spr2;
extern playersprite_t free_spr2;
typedef enum mobj_type
{

View File

@ -462,6 +462,8 @@ static int lib_pSpawnLockOn(lua_State *L)
return LUA_ErrInvalid(L, "mobj_t");
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (state >= NUMSTATES)
return luaL_error(L, "state %d out of range (0 - %d)", state, NUMSTATES-1);
if (P_IsLocalPlayer(player)) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker

View File

@ -127,6 +127,74 @@ static int lib_getSpr2name(lua_State *L)
return 0;
}
static int lib_getSpr2default(lua_State *L)
{
UINT32 i;
lua_remove(L, 1); // don't care about spr2defaults[] dummy userdata.
if (lua_isnumber(L, 1))
i = lua_tonumber(L, 1);
else if (lua_isstring(L, 1))
{
const char *name = lua_tostring(L, 1);
for (i = 0; i < free_spr2; i++)
if (fastcmp(name, spr2names[i]))
break;
}
else
return luaL_error(L, "spr2defaults[] invalid index");
if (i >= free_spr2)
return 0;
lua_pushinteger(L, spr2defaults[i]);
return 1;
}
static int lib_setSpr2default(lua_State *L)
{
UINT32 i;
UINT8 j = 0;
lua_remove(L, 1); // don't care about spr2defaults[] dummy userdata.
if (lua_isnumber(L, 1))
i = lua_tonumber(L, 1);
else if (lua_isstring(L, 1))
{
const char *name = lua_tostring(L, 1);
for (i = 0; i < free_spr2; i++)
if (fastcmp(name, spr2names[i]))
break;
if (i == free_spr2)
return luaL_error(L, "spr2defaults[] invalid index");
}
else
return luaL_error(L, "spr2defaults[] invalid index");
if (i < SPR2_FIRSTFREESLOT || i >= free_spr2)
return luaL_error(L, "spr2defaults[] index %d out of range (%d - %d)", i, SPR2_FIRSTFREESLOT, free_spr2-1);
if (lua_isnumber(L, 2))
j = lua_tonumber(L, 2);
else if (lua_isstring(L, 2))
{
const char *name = lua_tostring(L, 2);
for (j = 0; j < free_spr2; j++)
if (fastcmp(name, spr2names[j]))
break;
if (j == free_spr2)
return luaL_error(L, "spr2defaults[] invalid index");
}
if (j >= free_spr2)
j = 0; // return luaL_error(L, "spr2defaults[] set %d out of range (%d - %d)", j, 0, free_spr2-1);
spr2defaults[i] = j;
return 0;
}
static int lib_spr2namelen(lua_State *L)
{
lua_pushinteger(L, free_spr2);
@ -984,6 +1052,19 @@ int LUA_InfoLib(lua_State *L)
lua_setmetatable(L, -2);
lua_setglobal(L, "spr2names");
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getSpr2default);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_setSpr2default);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, lib_spr2namelen);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "spr2defaults");
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getState);

View File

@ -2431,13 +2431,14 @@ CV_PossibleValue_t skin_cons_t[MAXSKINS+1];
UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
{
UINT8 super = (spr2 & FF_SPR2SUPER);
UINT8 super = (spr2 & FF_SPR2SUPER), i = 0;
if (!skin)
return 0;
while (!(skin->sprites[spr2].numframes)
&& spr2 != SPR2_STND)
&& spr2 != SPR2_STND
&& ++i != 32) // recursion limiter
{
if (spr2 & FF_SPR2SUPER)
{
@ -2447,83 +2448,18 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
switch(spr2)
{
case SPR2_RUN:
spr2 = SPR2_WALK;
break;
case SPR2_STUN:
spr2 = SPR2_PAIN;
break;
case SPR2_DRWN:
spr2 = SPR2_DEAD;
break;
case SPR2_SPIN:
spr2 = SPR2_ROLL;
break;
case SPR2_GASP:
spr2 = SPR2_SPNG;
break;
// Normal special cases.
case SPR2_JUMP:
spr2 = ((player
? player->charflags
: skin->flags)
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL;
break;
case SPR2_SPNG: // spring
spr2 = SPR2_FALL;
break;
case SPR2_FALL:
spr2 = SPR2_WALK;
break;
case SPR2_RIDE:
spr2 = SPR2_FALL;
break;
case SPR2_FLY :
spr2 = SPR2_SPNG;
break;
case SPR2_SWIM:
spr2 = SPR2_FLY ;
break;
case SPR2_TIRE:
spr2 = (player && player->charability == CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
break;
case SPR2_GLID:
spr2 = SPR2_FLY;
break;
case SPR2_CLMB:
spr2 = SPR2_ROLL;
break;
case SPR2_CLNG:
spr2 = SPR2_CLMB;
break;
case SPR2_FLT :
spr2 = SPR2_WALK;
break;
case SPR2_FRUN:
spr2 = SPR2_RUN ;
break;
case SPR2_DASH:
spr2 = SPR2_FRUN;
break;
case SPR2_BNCE:
spr2 = SPR2_FALL;
break;
case SPR2_BLND:
spr2 = SPR2_ROLL;
break;
case SPR2_TWIN:
spr2 = SPR2_ROLL;
break;
case SPR2_MLEE:
spr2 = SPR2_TWIN;
break;
// NiGHTS sprites.
case SPR2_NSTD:
spr2 = SPR2_STND;
@ -2535,72 +2471,16 @@ UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
break;
case SPR2_NSTN:
spr2 = SPR2_STUN;
break;
case SPR2_NPUL:
spr2 = SPR2_NSTN;
super = FF_SPR2SUPER;
break;
case SPR2_NATK:
spr2 = SPR2_ROLL;
super = FF_SPR2SUPER;
break;
/*case SPR2_NGT0:
spr2 = SPR2_NFLT;
break;*/
case SPR2_NGT1:
case SPR2_NGT7:
case SPR2_DRL0:
spr2 = SPR2_NGT0;
break;
case SPR2_NGT2:
case SPR2_DRL1:
spr2 = SPR2_NGT1;
break;
case SPR2_NGT3:
case SPR2_DRL2:
spr2 = SPR2_NGT2;
break;
case SPR2_NGT4:
case SPR2_DRL3:
spr2 = SPR2_NGT3;
break;
case SPR2_NGT5:
case SPR2_DRL4:
spr2 = SPR2_NGT4;
break;
case SPR2_NGT6:
case SPR2_DRL5:
spr2 = SPR2_NGT5;
break;
case SPR2_DRL6:
spr2 = SPR2_NGT6;
break;
case SPR2_NGT8:
case SPR2_DRL7:
spr2 = SPR2_NGT7;
break;
case SPR2_NGT9:
case SPR2_DRL8:
spr2 = SPR2_NGT8;
break;
case SPR2_NGTA:
case SPR2_DRL9:
spr2 = SPR2_NGT9;
break;
case SPR2_NGTB:
case SPR2_DRLA:
spr2 = SPR2_NGTA;
break;
case SPR2_NGTC:
case SPR2_DRLB:
spr2 = SPR2_NGTB;
break;
case SPR2_DRLC:
spr2 = SPR2_NGTC;
break;
// Dunno? Just go to standing then.
// Use the handy list, that's what it's there for!
default:
spr2 = SPR2_STND;
spr2 = spr2defaults[spr2];
break;
}