Implement frame ranges for SpriteInfo

This commit is contained in:
Lactozilla 2025-01-29 18:36:47 -03:00
parent 4aa8eb4bf3
commit d812a085af
2 changed files with 108 additions and 14 deletions

View file

@ -268,7 +268,7 @@ static int lib_getSpriteInfo(lua_State *L)
#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to spriteinfo[] (%s)", e);
#define TYPEERROR(f, t1, t2) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t1), lua_typename(L, t2)))
static int PopPivotSubTable(spriteframepivot_t *pivot, lua_State *L, int stk, int idx)
static int PopPivotSubTable(spriteinfo_t *info, lua_State *L, int stk, int idx)
{
int okcool = 0;
switch (lua_type(L, stk))
@ -306,9 +306,9 @@ static int PopPivotSubTable(spriteframepivot_t *pivot, lua_State *L, int stk, in
}
// Set it
if (ikey == 1 || (key && fastcmp(key, "x")))
pivot[idx].x = (INT32)value;
info->pivot[idx].x = (INT32)value;
else if (ikey == 2 || (key && fastcmp(key, "y")))
pivot[idx].y = (INT32)value;
info->pivot[idx].y = (INT32)value;
// TODO: 2.3: Delete
else if (ikey == 3 || (key && fastcmp(key, "rotaxis")))
LUA_UsageWarning(L, "\"rotaxis\" is deprecated and will be removed.")
@ -355,7 +355,7 @@ static int PopPivotTable(spriteinfo_t *info, lua_State *L, int stk)
if ((idx < 0) || (idx >= MAXFRAMENUM))
return luaL_error(L, "pivot frame %d out of range (0 - %d)", idx, MAXFRAMENUM - 1);
// the values in pivot[] are also tables
if (PopPivotSubTable(info->pivot, L, stk+2, idx))
if (PopPivotSubTable(info, L, stk+2, idx))
set_bit_array(info->available, idx);
lua_pop(L, 1);
}
@ -534,12 +534,14 @@ static int pivotlist_set(lua_State *L)
// pivot[] is a table
if (lua_istable(L, 3))
okcool = PopPivotSubTable(sprinfo->pivot, L, 3, frame);
okcool = PopPivotSubTable(sprinfo, L, 3, frame);
// pivot[] is userdata
else if (lua_isuserdata(L, 3))
{
struct PivotFrame *container = luaL_checkudata(L, 3, META_FRAMEPIVOT);
memcpy(&sprinfo->pivot[frame], &container->sprinfo->pivot[container->frame], sizeof(spriteframepivot_t));
memcpy(&sprinfo->pivot[frame],
&container->sprinfo->pivot[container->frame],
sizeof(spriteframepivot_t));
okcool = 1;
}

View file

@ -1551,11 +1551,39 @@ static void copy_to_skin (struct ParseSpriteInfoState *parser, INT32 skinnum)
}
}
struct ParsedSpriteInfoFrame {
INT32 pivotX;
INT32 pivotY;
};
static boolean define_spriteinfo_frame(struct ParsedSpriteInfoFrame *frame, spriteinfo_t *dest, UINT16 index)
{
boolean defined = false;
if (frame->pivotX != INT32_MAX)
{
dest->pivot[index].x = frame->pivotX;
defined = true;
}
if (frame->pivotY != INT32_MAX)
{
dest->pivot[index].y = frame->pivotY;
defined = true;
}
return defined;
}
static void R_ParseSpriteInfoFrame(struct ParseSpriteInfoState *parser, boolean all)
{
char *sprinfoToken;
size_t sprinfoTokenLength;
UINT16 frameID = 0;
UINT16 frameEndID = UINT16_MAX;
struct ParsedSpriteInfoFrame frame = {
.pivotX = INT32_MAX,
.pivotY = INT32_MAX
};
if (all)
{
@ -1564,18 +1592,65 @@ static void R_ParseSpriteInfoFrame(struct ParseSpriteInfoState *parser, boolean
else
{
// Sprite identifier
char *frameToken = NULL;
char *startRange = NULL;
char *endRange = NULL;
sprinfoToken = M_GetToken(NULL);
if (sprinfoToken == NULL)
{
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite frame should be");
}
sprinfoTokenLength = strlen(sprinfoToken);
if (sprinfoTokenLength != 1)
// Parse range
frameToken = Z_StrDup(sprinfoToken);
startRange = frameToken;
endRange = strstr(frameToken, "..");
if (endRange != NULL)
{
I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",sprinfoToken);
*endRange = '\0';
endRange += 2;
if (strstr(endRange, "."))
I_Error("Error parsing SPRTINFO lump: Invalid range \"%s\"",sprinfoToken);
}
int parseStartFrameID = -1;
if (!M_StringToNumber(startRange, &parseStartFrameID))
{
if (strlen(startRange) != 1)
I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",startRange);
parseStartFrameID = R_Char2Frame(startRange[0]);
if (parseStartFrameID == 255)
I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",startRange);
}
if (parseStartFrameID < 0 || parseStartFrameID >= MAXFRAMENUM)
I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",startRange);
frameID = (UINT16)parseStartFrameID;
// Parse range ID
if (endRange != NULL)
{
int parseEndFrameID = -1;
if (!M_StringToNumber(endRange, &parseEndFrameID))
{
if (strlen(endRange) != 1)
I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",endRange);
parseEndFrameID = R_Char2Frame(endRange[0]);
if (parseEndFrameID == 255)
I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",endRange);
}
if (parseEndFrameID < 0 || parseEndFrameID >= MAXFRAMENUM)
I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",endRange);
frameEndID = (UINT16)parseEndFrameID;
}
Z_Free(frameToken);
// Validate the range
if (frameEndID != UINT16_MAX && frameID >= frameEndID)
{
I_Error("Error parsing SPRTINFO lump: Invalid range \"%s\"",sprinfoToken);
}
frameID = R_Char2Frame(sprinfoToken[0]);
Z_Free(sprinfoToken);
}
@ -1599,13 +1674,13 @@ static void R_ParseSpriteInfoFrame(struct ParseSpriteInfoState *parser, boolean
{
Z_Free(sprinfoToken);
sprinfoToken = M_GetToken(NULL);
parser->info->pivot[frameID].x = atoi(sprinfoToken);
frame.pivotX = atoi(sprinfoToken);
}
else if (stricmp(sprinfoToken, "YPIVOT")==0)
{
Z_Free(sprinfoToken);
sprinfoToken = M_GetToken(NULL);
parser->info->pivot[frameID].y = atoi(sprinfoToken);
frame.pivotY = atoi(sprinfoToken);
}
else if (stricmp(sprinfoToken, "ROTAXIS")==0)
{
@ -1624,7 +1699,24 @@ static void R_ParseSpriteInfoFrame(struct ParseSpriteInfoState *parser, boolean
Z_Free(sprinfoToken);
}
set_bit_array(parser->info->available, frameID);
// Apply to the specified range of frames
if (frameEndID != UINT16_MAX)
{
for (UINT16 frameIter = frameID; frameIter <= frameEndID; frameIter++)
{
if (define_spriteinfo_frame(&frame, parser->info, frameIter))
{
set_bit_array(parser->info->available, frameIter);
}
}
}
else
{
if (define_spriteinfo_frame(&frame, parser->info, frameID))
{
set_bit_array(parser->info->available, frameID);
}
}
if (parser->spr2)
{