From 4aa8eb4bf390dba87df6db90ec415f779f333c36 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Wed, 29 Jan 2025 16:04:09 -0300 Subject: [PATCH] Update and extend R_ParseSpriteInfo for default pivot - Set default pivot with DEFAULT block - Use wildcard star (*) with Sprite/Sprite2Info/Skin to iterate over all sprites and/or skins Co-authored-by: James R --- src/r_patchrotation.c | 5 ++ src/r_picformats.c | 142 ++++++++++++++++++++++++++++++------------ src/r_picformats.h | 8 ++- 3 files changed, 113 insertions(+), 42 deletions(-) diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index 35b1e5d86..61129d608 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -101,6 +101,11 @@ patch_t *Patch_GetRotatedSprite( xpivot = sprinfo->pivot[frame].x; ypivot = sprinfo->pivot[frame].y; } + else if (R_IsSpriteInfoAvailable(sprinfo, SPRINFO_DEFAULT_FRAME)) + { + xpivot = sprinfo->pivot[SPRINFO_DEFAULT_FRAME].x; + ypivot = sprinfo->pivot[SPRINFO_DEFAULT_FRAME].y; + } else { xpivot = patch->leftoffset; diff --git a/src/r_picformats.c b/src/r_picformats.c index b9c34f33d..e0c6dd599 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -1484,10 +1484,14 @@ struct ParseSpriteInfoState { 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; @@ -1503,19 +1507,26 @@ static void R_ParseSpriteInfoSkin(struct ParseSpriteInfoState *parser) 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); + 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); + skinnum = R_SkinAvailable(skinName); + if (skinnum == -1) + I_Error("Error parsing SPRTINFO lump: Unknown skin \"%s\"", skinName); - parser->skinnumbers[parser->foundskins] = skinnum; - parser->foundskins++; + parser->skinnumbers[parser->foundskins] = skinnum; + parser->foundskins++; + } Z_Free(sprinfoToken); } @@ -1525,32 +1536,48 @@ static void copy_to_skin (struct ParseSpriteInfoState *parser, INT32 skinnum) skin_t *skin = skins[skinnum]; spriteinfo_t *sprinfo = skin->sprinfo; - M_Memcpy(&sprinfo[parser->spr2num], parser->info, sizeof(spriteinfo_t)); + 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) +static void R_ParseSpriteInfoFrame(struct ParseSpriteInfoState *parser, boolean all) { char *sprinfoToken; size_t sprinfoTokenLength; - char *frameChar = NULL; - UINT8 frameID = 0xFF; + UINT16 frameID = 0; - // Sprite identifier - sprinfoToken = M_GetToken(NULL); - if (sprinfoToken == NULL) + if (all) { - I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite frame should be"); - } - sprinfoTokenLength = strlen(sprinfoToken); - if (sprinfoTokenLength != 1) - { - I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",sprinfoToken); + frameID = SPRINFO_DEFAULT_FRAME; } else - frameChar = sprinfoToken; + { + // Sprite identifier + 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) + { + I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",sprinfoToken); + } - frameID = R_Char2Frame(frameChar[0]); - Z_Free(sprinfoToken); + frameID = R_Char2Frame(sprinfoToken[0]); + Z_Free(sprinfoToken); + } // Left Curly Brace sprinfoToken = M_GetToken(NULL); @@ -1606,14 +1633,36 @@ static void R_ParseSpriteInfoFrame(struct ParseSpriteInfoState *parser) if (!parser->foundskins) I_Error("Error parsing SPRTINFO lump: No skins specified in this sprite2 definition"); - for (i = 0; i < parser->foundskins; i++) + if (parser->foundskins < 0) { - copy_to_skin(parser, parser->skinnumbers[i]); + 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 { - M_Memcpy(&spriteinfo[parser->sprnum], parser->info, sizeof(spriteinfo_t)); + 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)); + } } } @@ -1632,6 +1681,7 @@ static void R_ParseSpriteInfo(boolean spr2) .spr2 = spr2, .sprnum = NUMSPRITES, .spr2num = NUMPLAYERSPRITES, + .any = false, .foundskins = 0, }; @@ -1644,15 +1694,24 @@ static void R_ParseSpriteInfo(boolean spr2) I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite name should be"); } - sprinfoTokenLength = strlen(sprinfoToken); - if (sprinfoTokenLength > MAXSPRITENAME) - I_Error("Error parsing SPRTINFO lump: Sprite name \"%s\" is longer than %d characters", sprinfoToken, MAXSPRITENAME); - strcpy(newSpriteName, sprinfoToken); - strupr(newSpriteName); // Just do this now so we don't have to worry about it + if (!strcmp(sprinfoToken, "*")) // All sprites + { + parser.any = true; + } + else + { + sprinfoTokenLength = strlen(sprinfoToken); + if (sprinfoTokenLength > MAXSPRITENAME) + I_Error("Error parsing SPRTINFO lump: Sprite name \"%s\" is longer than %d characters", sprinfoToken, MAXSPRITENAME); + strcpy(newSpriteName, sprinfoToken); + 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) { parser.sprnum = R_GetSpriteNumByName(newSpriteName); if (parser.sprnum == NUMSPRITES) @@ -1703,7 +1762,12 @@ static void R_ParseSpriteInfo(boolean spr2) else if (stricmp(sprinfoToken, "FRAME")==0) { Z_Free(sprinfoToken); - R_ParseSpriteInfoFrame(&parser); + R_ParseSpriteInfoFrame(&parser, PARSER_FRAME); + } + else if (stricmp(sprinfoToken, "DEFAULT")==0) + { + Z_Free(sprinfoToken); + R_ParseSpriteInfoFrame(&parser, PARSER_DEFAULT); } else { @@ -1790,7 +1854,7 @@ void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps) } } -boolean R_IsSpriteInfoAvailable(spriteinfo_t *info, UINT8 frame) +boolean R_IsSpriteInfoAvailable(spriteinfo_t *info, UINT16 frame) { - return info && in_bit_array(info->available, frame); + return info && frame <= SPRINFO_DEFAULT_FRAME && in_bit_array(info->available, frame); } diff --git a/src/r_picformats.h b/src/r_picformats.h index 653a2eab3..1388be013 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -98,10 +98,12 @@ typedef struct INT32 x, y; } spriteframepivot_t; +#define SPRINFO_DEFAULT_FRAME (MAXFRAMENUM) + typedef struct { - UINT8 available[BIT_ARRAY_SIZE(MAXFRAMENUM)]; - spriteframepivot_t pivot[MAXFRAMENUM]; + UINT8 available[BIT_ARRAY_SIZE(MAXFRAMENUM + 1)]; // 1 extra for default_frame + spriteframepivot_t pivot[MAXFRAMENUM + 1]; } spriteinfo_t; // PNG support @@ -126,6 +128,6 @@ extern spriteinfo_t spriteinfo[NUMSPRITES]; void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps); void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); -boolean R_IsSpriteInfoAvailable(spriteinfo_t *info, UINT8 frame); +boolean R_IsSpriteInfoAvailable(spriteinfo_t *info, UINT16 frame); #endif // __R_PICFORMATS__