From c2687432202a7d125d2d30f03635e9d4f05f6e1f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 29 Sep 2019 12:13:51 -0300 Subject: [PATCH] hehee --- src/dehacked.c | 2 +- src/hardware/hw_main.c | 10 +- src/p_setup.c | 8 ++ src/r_things.c | 292 ++++++++++++++++++++++++++++++++++++++++- src/r_things.h | 7 +- 5 files changed, 308 insertions(+), 11 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 3f7f6850e..e26f0d8e5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4008,7 +4008,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) } } #endif - else if (fastcmp(word, "SPRITE")) + else if (fastcmp(word, "SPRITEINFO")) { if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_sprite(word2); // find a sprite by name diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index aff802352..912eab1c3 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5530,6 +5530,7 @@ static void HWR_ProjectSprite(mobj_t *thing) float gz, gzt; spritedef_t *sprdef; spriteframe_t *sprframe; + spriteinfo_t *sprinfo; size_t lumpoff; unsigned rot; UINT8 flip; @@ -5583,9 +5584,15 @@ static void HWR_ProjectSprite(mobj_t *thing) //Fab : 02-08-98: 'skin' override spritedef currently used for skin if (thing->skin && thing->sprite == SPR_PLAY) + { sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; + sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; + } else + { sprdef = &sprites[thing->sprite]; + sprinfo = NULL; + } if (rot >= sprdef->numframes) { @@ -5594,6 +5601,7 @@ static void HWR_ProjectSprite(mobj_t *thing) thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; + sprinfo = NULL; rot = thing->frame&FF_FRAMEMASK; thing->state->sprite = thing->sprite; thing->state->frame = thing->frame; @@ -5658,7 +5666,7 @@ static void HWR_ProjectSprite(mobj_t *thing) if (rollangle > 0) { if (!sprframe->rotsprite.cached[rot]) - R_CacheRotSprite(thing->sprite, thing->frame, sprframe, rot, flip); + R_CacheRotSprite(thing->sprite, thing->frame, sprinfo, sprframe, rot, flip); rollangle /= ROTANGDIFF; rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) diff --git a/src/p_setup.c b/src/p_setup.c index 22990450e..047053f68 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3471,6 +3471,14 @@ boolean P_AddWadFile(const char *wadfilename) if (!mapsadded) CONS_Printf(M_GetText("No maps added\n")); + // load SPRTINFO lumps + for (i = 0; i < numlumps; i++, lumpinfo++) + { + name = lumpinfo->name; + if (!stricmp(name, "SPRTINFO")) + R_ParseSPRTINFOLump(wadnum, i); + } + // reload status bar (warning should have valid player!) if (gamestate == GS_LEVEL) ST_Start(); diff --git a/src/r_things.c b/src/r_things.c index fe2a20b12..87cc2e832 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -219,7 +219,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch } #ifdef ROTSPRITE -void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteframe_t *sprframe, INT32 rot, UINT8 flip) +void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip) { UINT32 i; INT32 angle; @@ -255,10 +255,14 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteframe_t *sprframe, // rotation pivot px = SPRITE_XCENTER; py = SPRITE_YCENTER; - if (spriteinfo[sprnum].available) + + // get correct sprite info for sprite + if (sprinfo == NULL) + sprinfo = &spriteinfo[sprnum]; + if (sprinfo->available) { - px = spriteinfo[sprnum].pivot[frame].x; - py = spriteinfo[sprnum].pivot[frame].y; + px = sprinfo->pivot[frame].x; + py = sprinfo->pivot[frame].y; } if (flip) px = width - px; @@ -322,7 +326,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteframe_t *sprframe, #define BOUNDARYWCHECK(b) (b[0] < 0 || b[0] >= width) #define BOUNDARYHCHECK(b) (b[1] < 0 || b[1] >= height) -#define BOUNDARYADJUST(x) x = 15*x/10 +#define BOUNDARYADJUST(x) x *= 2 // top left/right if (BOUNDARYWCHECK(top[0]) || BOUNDARYWCHECK(top[1])) BOUNDARYADJUST(newwidth); @@ -733,7 +737,8 @@ static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL // void R_InitSprites(void) { - size_t i; + size_t i, j; + lumpinfo_t *lumpinfo; #ifdef ROTSPRITE INT32 angle, realangle = 0; float fa; @@ -778,6 +783,13 @@ void R_InitSprites(void) { R_AddSkins((UINT16)i); R_PatchSkins((UINT16)i); + // load SPRTINFO lumps + lumpinfo = wadfiles[i]->lumpinfo; + for (j = 0; j < wadfiles[i]->numlumps; j++, lumpinfo++) + { + if (!stricmp(lumpinfo->name, "SPRTINFO")) + R_ParseSPRTINFOLump(i, j); + } } ST_ReloadSkinFaceGraphics(); @@ -1313,6 +1325,7 @@ static void R_ProjectSprite(mobj_t *thing) spritedef_t *sprdef; spriteframe_t *sprframe; + spriteinfo_t *sprinfo; size_t lump; size_t rot; @@ -1387,16 +1400,21 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->skin && thing->sprite == SPR_PLAY) { sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; + sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2]; if (rot >= sprdef->numframes) { CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(rot)); thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; + sprinfo = NULL; rot = thing->frame&FF_FRAMEMASK; } } else + { sprdef = &sprites[thing->sprite]; + sprinfo = NULL; + } if (rot >= sprdef->numframes) { @@ -1465,7 +1483,7 @@ static void R_ProjectSprite(mobj_t *thing) if (rollangle > 0) { if (!sprframe->rotsprite.cached[rot]) - R_CacheRotSprite(thing->sprite, thing->frame, sprframe, rot, flip); + R_CacheRotSprite(thing->sprite, thing->frame, sprinfo, sprframe, rot, flip); rollangle /= ROTANGDIFF; rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) @@ -3602,3 +3620,263 @@ next_token: #undef HUDNAMEWRITE #undef SYMBOLCONVERT + +// pain +static void R_ParseSpriteInfoFrame(spritenum_t sprnum, playersprite_t spr2num, INT32 skinnum) +{ + char *sprinfoToken; + size_t sprinfoTokenLength; + char *frameChar; + UINT8 frameFrame; + boolean sprite2available = (spr2num != NUMPLAYERSPRITES); +#ifdef ROTSPRITE + INT16 frameXPivot = 0; + INT16 frameYPivot = 0; +#endif + + if (sprite2available && (skinnum == -1)) + I_Error("Error parsing SPRTINFO lump: Missing skin for sprite2 definition"); + + // 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); + } + else + frameChar = sprinfoToken; + + frameFrame = R_Char2Frame(frameChar[0]); + Z_Free(sprinfoToken); + + // Left Curly Brace + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + I_Error("Error parsing SPRTINFO lump: Missing sprite info"); + else + { + if (strcmp(sprinfoToken,"{")==0) + { + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info should be"); + } + while (strcmp(sprinfoToken,"}")!=0) + { +#ifdef ROTSPRITE + if (stricmp(sprinfoToken, "XPIVOT")==0) + { + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + frameXPivot = atoi(sprinfoToken); + } + else if (stricmp(sprinfoToken, "YPIVOT")==0) + { + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + frameYPivot = atoi(sprinfoToken); + } +#endif + Z_Free(sprinfoToken); + + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info or right curly brace should be"); + } + } + } + Z_Free(sprinfoToken); + } + + if (sprite2available) + { + skin_t *skin = &skins[skinnum]; + spriteinfo_t *sprinfo = skin->sprinfo; + + sprinfo[spr2num].available = true; + +#ifdef ROTSPRITE + sprinfo[spr2num].pivot[frameFrame].x = frameXPivot; + sprinfo[spr2num].pivot[frameFrame].y = frameYPivot; +#endif + } + else + { + spriteinfo[sprnum].available = true; +#ifdef ROTSPRITE + spriteinfo[sprnum].pivot[frameFrame].x = frameXPivot; + spriteinfo[sprnum].pivot[frameFrame].y = frameYPivot; +#endif + } +} + +static void R_ParseSpriteInfo(boolean spr2) +{ + char *sprinfoToken; + size_t sprinfoTokenLength; + char newSpriteName[5]; // no longer dynamically allocated + spritenum_t sprnum = NUMSPRITES; + playersprite_t spr2num = NUMPLAYERSPRITES; + INT32 i; + INT32 skinnum = -1; + + // Texture name + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite name should be"); + } + sprinfoTokenLength = strlen(sprinfoToken); + if (sprinfoTokenLength != 4) + { + I_Error("Error parsing SPRTINFO lump: Sprite name \"%s\" isn't 4 characters",sprinfoToken); + } + else + { + memset(&newSpriteName, 0, 5); + M_Memcpy(newSpriteName, sprinfoToken, sprinfoTokenLength); + // ^^ 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) + { + for (i = 0; i <= NUMSPRITES; i++) + { + if (i == NUMSPRITES) + I_Error("Error parsing SPRTINFO lump: Unknown sprite name \"%s\"", newSpriteName); + if (!memcmp(newSpriteName,sprnames[i],4)) + { + sprnum = i; + break; + } + } + } + else + { + for (i = 0; i <= NUMPLAYERSPRITES; i++) + { + if (i == NUMPLAYERSPRITES) + I_Error("Error parsing SPRTINFO lump: Unknown sprite2 name \"%s\"", newSpriteName); + if (!memcmp(newSpriteName,spr2names[i],4)) + { + spr2num = i; + break; + } + } + } + + // Left Curly Brace + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where open curly brace for sprite \"%s\" should be",newSpriteName); + } + if (strcmp(sprinfoToken,"{")==0) + { + Z_Free(sprinfoToken); + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where definition for sprite \"%s\" should be",newSpriteName); + } + while (strcmp(sprinfoToken,"}")!=0) + { + if (stricmp(sprinfoToken, "SKIN")==0) + { + char *skinName = NULL; + if (!spr2) + I_Error("Error parsing SPRTINFO lump: \"SKIN\" token found outside of a sprite2 definition"); + + // Skin name + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where skin frame should be"); + } + sprinfoTokenLength = strlen(sprinfoToken); + + skinName = (char *)Z_Malloc((sprinfoTokenLength+1)*sizeof(char),PU_STATIC,NULL); + M_Memcpy(skinName,sprinfoToken,sprinfoTokenLength*sizeof(char)); + skinName[sprinfoTokenLength] = '\0'; + + Z_Free(sprinfoToken); + + strlwr(skinName); + skinnum = R_SkinAvailable(skinName); + if (skinnum == -1) + I_Error("Error parsing SPRTINFO lump: Unknown skin \"%s\"", skinName); + } + else if (stricmp(sprinfoToken, "FRAME")==0) + { + Z_Free(sprinfoToken); + R_ParseSpriteInfoFrame(sprnum, spr2num, skinnum); + } + else + { + I_Error("Error parsing SPRTINFO lump: Unknown keyword \"%s\" in sprite %s",sprinfoToken,newSpriteName); + } + + sprinfoToken = M_GetToken(NULL); + if (sprinfoToken == NULL) + { + I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info or right curly brace for sprite \"%s\" should be",newSpriteName); + } + } + } + else + { + I_Error("Error parsing SPRTINFO lump: Expected \"{\" for sprite \"%s\", got \"%s\"",newSpriteName,sprinfoToken); + } + Z_Free(sprinfoToken); +} + +// This is all just copy-pasted from R_ParseTEXTURESLump +void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum) +{ + char *sprinfoLump; + size_t sprinfoLumpLength; + char *sprinfoText; + char *sprinfoToken; + + // Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll + // need to make a space of memory where I can ensure that it will terminate + // correctly. Start by loading the relevant data from the WAD. + sprinfoLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC); + // If that didn't exist, we have nothing to do here. + if (sprinfoLump == NULL) return; + // If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly. + sprinfoLumpLength = W_LumpLengthPwad(wadNum, lumpNum); + sprinfoText = (char *)Z_Malloc((sprinfoLumpLength+1)*sizeof(char),PU_STATIC,NULL); + // Now move the contents of the lump into this new location. + memmove(sprinfoText,sprinfoLump,sprinfoLumpLength); + // Make damn well sure the last character in our new memory location is \0. + sprinfoText[sprinfoLumpLength] = '\0'; + // Finally, free up the memory from the first data load, because we really + // don't need it. + Z_Free(sprinfoLump); + + sprinfoToken = M_GetToken(sprinfoText); + while (sprinfoToken != NULL) + { + if (!stricmp(sprinfoToken, "SPRITE") || !stricmp(sprinfoToken, "SPRITE2")) + { + Z_Free(sprinfoToken); + R_ParseSpriteInfo(!stricmp(sprinfoToken, "SPRITE2")); + } + else + I_Error("Error parsing SPRTINFO lump: Unknown keyword \"%s\"", sprinfoToken); + sprinfoToken = M_GetToken(NULL); + } + Z_Free(sprinfoToken); + Z_Free((void *)sprinfoText); +} diff --git a/src/r_things.h b/src/r_things.h index aa1c92607..281d430d3 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -53,7 +53,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight); void R_AddSpriteDefs(UINT16 wadnum); #ifdef ROTSPRITE -void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteframe_t *sprframe, INT32 rot, UINT8 flip); +void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip); #endif //SoM: 6/5/2000: Light sprites correctly! @@ -133,7 +133,9 @@ typedef struct // specific sounds per skin sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table - spritedef_t sprites[NUMPLAYERSPRITES*2]; // contains super versions too + // contains super versions too + spritedef_t sprites[NUMPLAYERSPRITES*2]; + spriteinfo_t sprinfo[NUMPLAYERSPRITES*2]; UINT8 availability; // lock? } skin_t; @@ -237,6 +239,7 @@ UINT32 R_GetSkinAvailabilities(void); INT32 R_SkinAvailable(const char *name); void R_PatchSkins(UINT16 wadnum); void R_AddSkins(UINT16 wadnum); +void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player);