Merge branch 'pivot-default' into 'master'

Upgrade SPRTINFO -- default pivot offsets + wildcard

See merge request KartKrew/Kart!691
This commit is contained in:
Sal 2022-09-23 15:19:05 +00:00
commit 2890ce500a
7 changed files with 243 additions and 374 deletions

View file

@ -640,242 +640,6 @@ void readlight(MYFILE *f, INT32 num)
}
#endif // HWRENDER
static void readspriteframe(MYFILE *f, spriteinfo_t *sprinfo, UINT8 frame)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word, *word2;
char *tmp;
INT32 value;
char *lastline;
do
{
lastline = f->curpos;
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
// First remove trailing newline, if there is one
tmp = strchr(s, '\n');
if (tmp)
*tmp = '\0';
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
if (s == tmp)
continue; // Skip comment lines, but don't break.
// Set / reset word
word = s;
while ((*word == '\t') || (*word == ' '))
word++;
// Get the part before the " = "
tmp = strchr(s, '=');
if (tmp)
{
*(tmp-1) = '\0';
// Now get the part after
word2 = tmp += 2;
}
else
{
// Get the part before the " "
tmp = strchr(s, ' ');
if (tmp)
{
*tmp = '\0';
// Now get the part after
tmp++;
word2 = tmp;
}
else
break;
}
strupr(word);
value = atoi(word2); // used for numerical settings
if (fastcmp(word, "XPIVOT"))
sprinfo->pivot[frame].x = value;
else if (fastcmp(word, "YPIVOT"))
sprinfo->pivot[frame].y = value;
else if (fastcmp(word, "ROTAXIS"))
sprinfo->pivot[frame].rotaxis = value;
else
{
f->curpos = lastline;
break;
}
}
} while (!myfeof(f)); // finish when the line is empty
Z_Free(s);
}
void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word, *word2;
char *tmp;
#ifdef HWRENDER
INT32 value;
#endif
char *lastline;
INT32 skinnumbers[MAXSKINS];
INT32 foundskins = 0;
// allocate a spriteinfo
spriteinfo_t *info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL);
info->available = true;
do
{
lastline = f->curpos;
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
// First remove trailing newline, if there is one
tmp = strchr(s, '\n');
if (tmp)
*tmp = '\0';
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
if (s == tmp)
continue; // Skip comment lines, but don't break.
// Set / reset word
word = s;
while ((*word == '\t') || (*word == ' '))
word++;
// Get the part before the " = "
tmp = strchr(s, '=');
if (tmp)
{
*(tmp-1) = '\0';
// Now get the part after
word2 = tmp += 2;
}
else
{
// Get the part before the " "
tmp = strchr(s, ' ');
if (tmp)
{
*tmp = '\0';
// Now get the part after
tmp++;
word2 = tmp;
}
else
break;
}
strupr(word);
#ifdef HWRENDER
value = atoi(word2); // used for numerical settings
if (fastcmp(word, "LIGHTTYPE"))
{
if (sprite2)
deh_warning("Sprite2 %s: invalid word '%s'", spr2names[num], word);
else
{
INT32 oldvar;
for (oldvar = 0; t_lspr[num] != &lspr[oldvar]; oldvar++)
;
t_lspr[num] = &lspr[value];
}
}
else
#endif
if (fastcmp(word, "SKIN"))
{
INT32 skinnum = -1;
if (!sprite2)
{
deh_warning("Sprite %s: %s keyword found outside of SPRITE2INFO block, ignoring", spr2names[num], word);
continue;
}
// make lowercase
strlwr(word2);
skinnum = R_SkinAvailable(word2);
if (skinnum == -1)
{
deh_warning("Sprite2 %s: unknown skin %s", spr2names[num], word2);
break;
}
skinnumbers[foundskins] = skinnum;
foundskins++;
}
else if (fastcmp(word, "DEFAULT"))
{
if (!sprite2)
{
deh_warning("Sprite %s: %s keyword found outside of SPRITE2INFO block, ignoring", spr2names[num], word);
continue;
}
if (num < (INT32)free_spr2 && num >= (INT32)SPR2_FIRSTFREESLOT)
spr2defaults[num] = get_number(word2);
else
{
deh_warning("Sprite2 %s: out of range (%d - %d), ignoring", spr2names[num], SPR2_FIRSTFREESLOT, free_spr2-1);
continue;
}
}
else if (fastcmp(word, "FRAME"))
{
UINT8 frame = R_Char2Frame(word2[0]);
// frame number too high
if (frame >= 64)
{
if (sprite2)
deh_warning("Sprite2 %s: invalid frame %s", spr2names[num], word2);
else
deh_warning("Sprite %s: invalid frame %s", sprnames[num], word2);
break;
}
// read sprite frame and store it in the spriteinfo_t struct
readspriteframe(f, info, frame);
if (sprite2)
{
INT32 i;
if (!foundskins)
{
deh_warning("Sprite2 %s: no skins specified", spr2names[num]);
break;
}
for (i = 0; i < foundskins; i++)
{
size_t skinnum = skinnumbers[i];
skin_t *skin = &skins[skinnum];
spriteinfo_t *sprinfo = skin->sprinfo;
M_Memcpy(&sprinfo[num], info, sizeof(spriteinfo_t));
}
}
else
M_Memcpy(&spriteinfo[num], info, sizeof(spriteinfo_t));
}
else
{
//deh_warning("Sprite %s: unknown word '%s'", sprnames[num], word);
f->curpos = lastline;
break;
}
}
} while (!myfeof(f)); // finish when the line is empty
Z_Free(s);
Z_Free(info);
}
void readsprite2(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);

View file

@ -71,7 +71,6 @@ void readcutscene(MYFILE *f, INT32 num);
void readlevelheader(MYFILE *f, INT32 num);
void readgametype(MYFILE *f, char *gtname);
void readsprite2(MYFILE *f, INT32 num);
void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2);
#ifdef HWRENDER
void readlight(MYFILE *f, INT32 num);
#endif

View file

@ -356,30 +356,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
}
}
#endif
else if (fastcmp(word, "SPRITE") || fastcmp(word, "SPRITEINFO"))
{
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)
readspriteinfo(f, i, false);
else
{
deh_warning("Sprite number %d out of range (0 - %d)", i, NUMSPRITES-1);
ignorelines(f);
}
}
else if (fastcmp(word, "SPRITE2INFO"))
{
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_sprite2(word2); // find a sprite by name
if (i < NUMPLAYERSPRITES && i >= 0)
readspriteinfo(f, i, true);
else
{
deh_warning("Sprite2 number %d out of range (0 - %d)", i, NUMPLAYERSPRITES-1);
ignorelines(f);
}
}
else if (fastcmp(word, "LEVEL"))
{
// Support using the actual map name,

View file

@ -242,6 +242,30 @@ static int lib_spr2namelen(lua_State *L)
// SPRITE INFO //
/////////////////
struct PivotFrame {
spriteinfo_t *sprinfo;
UINT8 frame;
};
static UINT8 GetPivotFrame(lua_State *L, int idx)
{
const char *field = luaL_checkstring(L, idx);
UINT8 frame;
if (fastcmp("default", field))
{
frame = SPRINFO_DEFAULT_PIVOT;
}
else
{
frame = R_Char2Frame(field[0]);
if (frame == 255)
luaL_error(L, "invalid frame %s", field);
}
return frame;
}
// spriteinfo[]
static int lib_getSpriteInfo(lua_State *L)
{
@ -349,24 +373,23 @@ static int PopPivotTable(spriteinfo_t *info, lua_State *L, int stk)
while (lua_next(L, stk))
{
int idx = 0;
const char *framestr = NULL;
switch (lua_type(L, stk+1))
{
case LUA_TSTRING:
framestr = lua_tostring(L, stk+1);
idx = R_Char2Frame(framestr[0]);
idx = GetPivotFrame(L, stk+1);
break;
case LUA_TNUMBER:
idx = lua_tonumber(L, stk+1);
if ((idx < 0) || (idx >= 64))
return luaL_error(L, "pivot frame %d out of range (0 - %d)", idx, 63);
break;
default:
TYPEERROR("pivot frame", LUA_TNUMBER, lua_type(L, stk+1));
}
if ((idx < 0) || (idx >= 64))
return luaL_error(L, "pivot frame %d out of range (0 - %d)", idx, 63);
// the values in pivot[] are also tables
if (PopPivotSubTable(info->pivot, L, stk+2, idx))
info->available = true;
set_bit_array(info->available, idx);
lua_pop(L, 1);
}
@ -441,7 +464,7 @@ static int spriteinfo_get(lua_State *L)
{
// bypass LUA_PushUserdata
void **userdata = lua_newuserdata(L, sizeof(void *));
*userdata = &sprinfo->pivot;
*userdata = sprinfo;
luaL_getmetatable(L, META_PIVOTLIST);
lua_setmetatable(L, -2);
@ -480,9 +503,8 @@ static int spriteinfo_set(lua_State *L)
// pivot[] is userdata
else if (lua_isuserdata(L, 1))
{
spriteframepivot_t *pivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_PIVOTLIST));
memcpy(&sprinfo->pivot, pivot, sizeof(spriteframepivot_t));
sprinfo->available = true; // Just in case?
spriteinfo_t *copyinfo = *((spriteinfo_t **)luaL_checkudata(L, 1, META_PIVOTLIST));
memcpy(sprinfo, copyinfo, sizeof(spriteinfo_t));
}
}
else
@ -505,20 +527,16 @@ static int spriteinfo_num(lua_State *L)
// framepivot_t
static int pivotlist_get(lua_State *L)
{
void **userdata;
spriteframepivot_t *framepivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_PIVOTLIST));
const char *field = luaL_checkstring(L, 2);
UINT8 frame;
struct PivotFrame *container;
spriteinfo_t *sprinfo = *((spriteinfo_t **)luaL_checkudata(L, 1, META_PIVOTLIST));
UINT8 frame = GetPivotFrame(L, 2);
I_Assert(framepivot != NULL);
frame = R_Char2Frame(field[0]);
if (frame == 255)
luaL_error(L, "invalid frame %s", field);
// bypass LUA_PushUserdata
userdata = lua_newuserdata(L, sizeof(void *));
*userdata = &framepivot[frame];
container = lua_newuserdata(L, sizeof *container);
container->sprinfo = sprinfo;
container->frame = frame;
luaL_getmetatable(L, META_FRAMEPIVOT);
lua_setmetatable(L, -2);
@ -528,11 +546,9 @@ static int pivotlist_get(lua_State *L)
static int pivotlist_set(lua_State *L)
{
// Because I already know it's a spriteframepivot_t anyway
spriteframepivot_t *pivotlist = *((spriteframepivot_t **)lua_touserdata(L, 1));
//spriteframepivot_t *framepivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_FRAMEPIVOT));
const char *field = luaL_checkstring(L, 2);
spriteinfo_t *sprinfo = *((spriteinfo_t **)luaL_checkudata(L, 1, META_PIVOTLIST));
UINT8 frame;
int okcool = 0;
if (!lua_lumploading)
return luaL_error(L, "Do not alter spriteframepivot_t from within a hook or coroutine!");
@ -543,20 +559,22 @@ static int pivotlist_set(lua_State *L)
I_Assert(pivotlist != NULL);
frame = R_Char2Frame(field[0]);
if (frame == 255)
luaL_error(L, "invalid frame %s", field);
frame = GetPivotFrame(L, 2);
// pivot[] is a table
if (lua_istable(L, 3))
return PopPivotSubTable(pivotlist, L, 3, frame);
okcool = PopPivotSubTable(sprinfo->pivot, L, 3, frame);
// pivot[] is userdata
else if (lua_isuserdata(L, 3))
{
spriteframepivot_t *copypivot = *((spriteframepivot_t **)luaL_checkudata(L, 3, META_FRAMEPIVOT));
memcpy(&pivotlist[frame], copypivot, sizeof(spriteframepivot_t));
struct PivotFrame *container = luaL_checkudata(L, 3, META_FRAMEPIVOT);
memcpy(&sprinfo->pivot[frame], &container->sprinfo->pivot[container->frame], sizeof(spriteframepivot_t));
okcool = 1;
}
if (okcool)
set_bit_array(sprinfo->available, frame);
return 0;
}
@ -568,7 +586,8 @@ static int pivotlist_num(lua_State *L)
static int framepivot_get(lua_State *L)
{
spriteframepivot_t *framepivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_FRAMEPIVOT));
struct PivotFrame *container = luaL_checkudata(L, 1, META_FRAMEPIVOT);
spriteframepivot_t *framepivot = &container->sprinfo->pivot[container->frame];
const char *field = luaL_checkstring(L, 2);
I_Assert(framepivot != NULL);
@ -585,7 +604,9 @@ static int framepivot_get(lua_State *L)
static int framepivot_set(lua_State *L)
{
spriteframepivot_t *framepivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_FRAMEPIVOT));
struct PivotFrame *container = luaL_checkudata(L, 1, META_FRAMEPIVOT);
spriteframepivot_t *framepivot = &container->sprinfo->pivot[container->frame];
UINT8 *available = container->sprinfo->available;
const char *field = luaL_checkstring(L, 2);
if (!lua_lumploading)
@ -598,9 +619,15 @@ static int framepivot_set(lua_State *L)
I_Assert(framepivot != NULL);
if (fastcmp("x", field))
{
framepivot->x = luaL_checkinteger(L, 3);
set_bit_array(available, container->frame);
}
else if (fastcmp("y", field))
{
framepivot->y = luaL_checkinteger(L, 3);
set_bit_array(available, container->frame);
}
else
return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field));

View file

@ -141,11 +141,16 @@ patch_t *Patch_GetRotatedSprite(
patch = W_CachePatchNum(lump, PU_SPRITE);
if (sprinfo->available)
if (in_bit_array(sprinfo->available, frame))
{
xpivot = sprinfo->pivot[frame].x;
ypivot = sprinfo->pivot[frame].y;
}
else if (in_bit_array(sprinfo->available, SPRINFO_DEFAULT_PIVOT))
{
xpivot = sprinfo->pivot[SPRINFO_DEFAULT_PIVOT].x;
ypivot = sprinfo->pivot[SPRINFO_DEFAULT_PIVOT].y;
}
else
{
xpivot = patch->leftoffset;

View file

@ -1396,12 +1396,79 @@ boolean Picture_PNGDimensions(UINT8 *png, INT32 *width, INT32 *height, INT16 *to
#endif
#endif
//
// R_ParseSpriteInfoFrame
//
// Parse a SPRTINFO frame.
//
static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
struct ParseSpriteInfoState {
boolean spr2;
spriteinfo_t *info;
spritenum_t sprnum;
playersprite_t spr2num;
boolean any;
INT32 skinnumbers[MAXSKINS];
INT32 foundskins;
};
#define PARSER_FRAME (false)
#define PARSER_DEFAULT (true)
static void R_ParseSpriteInfoSkin(struct ParseSpriteInfoState *parser)
{
char *sprinfoToken;
size_t sprinfoTokenLength;
INT32 skinnum;
char *skinName = NULL;
// Skin name
sprinfoToken = M_GetToken(NULL);
if (sprinfoToken == NULL)
{
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where skin frame should be");
}
if (strcmp(sprinfoToken, "*")==0) // All skins
{
parser->foundskins = -1;
}
else
{
// copy skin name yada yada
sprinfoTokenLength = strlen(sprinfoToken);
skinName = (char *)Z_Malloc((sprinfoTokenLength+1)*sizeof(char),PU_STATIC,NULL);
M_Memcpy(skinName,sprinfoToken,sprinfoTokenLength*sizeof(char));
skinName[sprinfoTokenLength] = '\0';
strlwr(skinName);
skinnum = R_SkinAvailable(skinName);
if (skinnum == -1)
I_Error("Error parsing SPRTINFO lump: Unknown skin \"%s\"", skinName);
parser->skinnumbers[parser->foundskins] = skinnum;
parser->foundskins++;
}
Z_Free(sprinfoToken);
}
static void copy_to_skin (struct ParseSpriteInfoState *parser, INT32 skinnum)
{
skin_t *skin = &skins[skinnum];
spriteinfo_t *sprinfo = skin->sprinfo;
if (parser->any)
{
playersprite_t spr2num;
for (spr2num = 0; spr2num < NUMPLAYERSPRITES; ++spr2num)
{
M_Memcpy(&sprinfo[spr2num], parser->info, sizeof(spriteinfo_t));
}
}
else
{
M_Memcpy(&sprinfo[parser->spr2num], parser->info, sizeof(spriteinfo_t));
}
}
static void R_ParseSpriteInfoFrame(struct ParseSpriteInfoState *parser, boolean all)
{
char *sprinfoToken;
size_t sprinfoTokenLength;
@ -1411,6 +1478,12 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
INT16 frameYPivot = 0;
rotaxis_t frameRotAxis = 0;
if (all)
{
frameFrame = SPRINFO_DEFAULT_PIVOT;
}
else
{
// Sprite identifier
sprinfoToken = M_GetToken(NULL);
if (sprinfoToken == NULL)
@ -1427,6 +1500,7 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
frameFrame = R_Char2Frame(frameChar[0]);
Z_Free(sprinfoToken);
}
// Left Curly Brace
sprinfoToken = M_GetToken(NULL);
@ -1480,9 +1554,50 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
}
// set fields
info->pivot[frameFrame].x = frameXPivot;
info->pivot[frameFrame].y = frameYPivot;
info->pivot[frameFrame].rotaxis = frameRotAxis;
parser->info->pivot[frameFrame].x = frameXPivot;
parser->info->pivot[frameFrame].y = frameYPivot;
parser->info->pivot[frameFrame].rotaxis = frameRotAxis;
set_bit_array(parser->info->available, frameFrame);
if (parser->spr2)
{
INT32 i;
if (!parser->foundskins)
I_Error("Error parsing SPRTINFO lump: No skins specified in this sprite2 definition");
if (parser->foundskins < 0)
{
for (i = 0; i < numskins; i++)
{
copy_to_skin(parser, i);
}
}
else
{
for (i = 0; i < parser->foundskins; i++)
{
copy_to_skin(parser, parser->skinnumbers[i]);
}
}
}
else
{
if (parser->any)
{
spritenum_t sprnum;
for (sprnum = 0; sprnum < NUMSPRITES; ++sprnum)
{
M_Memcpy(&spriteinfo[sprnum], parser->info, sizeof(spriteinfo_t));
}
}
else
{
M_Memcpy(&spriteinfo[parser->sprnum], parser->info, sizeof(spriteinfo_t));
}
}
}
//
@ -1492,15 +1607,19 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
//
static void R_ParseSpriteInfo(boolean spr2)
{
spriteinfo_t *info;
char *sprinfoToken;
size_t sprinfoTokenLength;
char newSpriteName[5]; // no longer dynamically allocated
spritenum_t sprnum = NUMSPRITES;
playersprite_t spr2num = NUMPLAYERSPRITES;
struct ParseSpriteInfoState parser = {
.spr2 = spr2,
.sprnum = NUMSPRITES,
.spr2num = NUMPLAYERSPRITES,
.any = false,
.foundskins = 0,
};
INT32 i;
INT32 skinnumbers[MAXSKINS];
INT32 foundskins = 0;
// Sprite name
sprinfoToken = M_GetToken(NULL);
@ -1508,6 +1627,13 @@ static void R_ParseSpriteInfo(boolean spr2)
{
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite name should be");
}
if (!strcmp(sprinfoToken, "*")) // All sprites
{
parser.any = true;
}
else
{
sprinfoTokenLength = strlen(sprinfoToken);
if (sprinfoTokenLength != 4)
{
@ -1520,9 +1646,13 @@ static void R_ParseSpriteInfo(boolean spr2)
// ^^ we've confirmed that the token is == 4 characters so it will never overflow a 5 byte char buffer
strupr(newSpriteName); // Just do this now so we don't have to worry about it
}
}
Z_Free(sprinfoToken);
if (!spr2)
if (parser.any)
;
else if (!spr2)
{
for (i = 0; i <= NUMSPRITES; i++)
{
@ -1530,7 +1660,7 @@ static void R_ParseSpriteInfo(boolean spr2)
I_Error("Error parsing SPRTINFO lump: Unknown sprite name \"%s\"", newSpriteName);
if (!memcmp(newSpriteName,sprnames[i],4))
{
sprnum = i;
parser.sprnum = i;
break;
}
}
@ -1543,15 +1673,14 @@ static void R_ParseSpriteInfo(boolean spr2)
I_Error("Error parsing SPRTINFO lump: Unknown sprite2 name \"%s\"", newSpriteName);
if (!memcmp(newSpriteName,spr2names[i],4))
{
spr2num = i;
parser.spr2num = i;
break;
}
}
}
// allocate a spriteinfo
info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL);
info->available = true;
parser.info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL);
// Left Curly Brace
sprinfoToken = M_GetToken(NULL);
@ -1571,53 +1700,21 @@ static void R_ParseSpriteInfo(boolean spr2)
{
if (stricmp(sprinfoToken, "SKIN")==0)
{
INT32 skinnum;
char *skinName = NULL;
if (!spr2)
I_Error("Error parsing SPRTINFO lump: \"SKIN\" token found outside of a sprite2 definition");
Z_Free(sprinfoToken);
// Skin name
sprinfoToken = M_GetToken(NULL);
if (sprinfoToken == NULL)
{
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where skin frame should be");
}
// copy skin name yada yada
sprinfoTokenLength = strlen(sprinfoToken);
skinName = (char *)Z_Malloc((sprinfoTokenLength+1)*sizeof(char),PU_STATIC,NULL);
M_Memcpy(skinName,sprinfoToken,sprinfoTokenLength*sizeof(char));
skinName[sprinfoTokenLength] = '\0';
strlwr(skinName);
Z_Free(sprinfoToken);
skinnum = R_SkinAvailable(skinName);
if (skinnum == -1)
I_Error("Error parsing SPRTINFO lump: Unknown skin \"%s\"", skinName);
skinnumbers[foundskins] = skinnum;
foundskins++;
R_ParseSpriteInfoSkin(&parser);
}
else if (stricmp(sprinfoToken, "FRAME")==0)
{
R_ParseSpriteInfoFrame(info);
Z_Free(sprinfoToken);
if (spr2)
{
if (!foundskins)
I_Error("Error parsing SPRTINFO lump: No skins specified in this sprite2 definition");
for (i = 0; i < foundskins; i++)
{
size_t skinnum = skinnumbers[i];
skin_t *skin = &skins[skinnum];
spriteinfo_t *sprinfo = skin->sprinfo;
M_Memcpy(&sprinfo[spr2num], info, sizeof(spriteinfo_t));
R_ParseSpriteInfoFrame(&parser, PARSER_FRAME);
}
}
else
M_Memcpy(&spriteinfo[sprnum], info, sizeof(spriteinfo_t));
else if (stricmp(sprinfoToken, "DEFAULT")==0)
{
Z_Free(sprinfoToken);
R_ParseSpriteInfoFrame(&parser, PARSER_DEFAULT);
}
else
{
@ -1636,7 +1733,7 @@ static void R_ParseSpriteInfo(boolean spr2)
I_Error("Error parsing SPRTINFO lump: Expected \"{\" for sprite \"%s\", got \"%s\"",newSpriteName,sprinfoToken);
}
Z_Free(sprinfoToken);
Z_Free(info);
Z_Free(parser.info);
}
//

View file

@ -100,8 +100,9 @@ typedef struct
typedef struct
{
spriteframepivot_t pivot[64];
boolean available;
spriteframepivot_t pivot[64 + 1];
#define SPRINFO_DEFAULT_PIVOT (64)
UINT8 available[BIT_ARRAY_SIZE(64 + 1)]; // 1 extra for default_pivot
} spriteinfo_t;
// Portable Network Graphics