From 9ca5ce01f1fde4680820af7d0e31dc7ce38181fd Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 14 Mar 2024 13:56:47 +0100 Subject: [PATCH 01/32] No longer store wadnum in sprnames --- src/deh_lua.c | 11 +---------- src/deh_soc.c | 7 +------ src/lua_script.c | 3 --- src/r_things.c | 3 --- 4 files changed, 2 insertions(+), 22 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index c056db82a..b73479263 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -59,23 +59,14 @@ static inline int lib_freeslot(lua_State *L) } else if (fastcmp(type, "SPR")) { - char wad; spritenum_t j; - lua_getfield(L, LUA_REGISTRYINDEX, "WAD"); - wad = (char)lua_tointeger(L, -1); - lua_pop(L, 1); for (j = SPR_FIRSTFREESLOT; j <= SPR_LASTFREESLOT; j++) { if (used_spr[(j-SPR_FIRSTFREESLOT)/8] & (1<<(j%8))) - { - if (!sprnames[j][4] && memcmp(sprnames[j],word,4)==0) - sprnames[j][4] = wad; continue; // Already allocated, next. - } // Found a free slot! CONS_Printf("Sprite SPR_%s allocated.\n",word); strncpy(sprnames[j],word,4); - //sprnames[j][4] = 0; used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now. // Lua needs to update the value in _G if it exists LUA_UpdateSprName(word, j); @@ -456,7 +447,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) else if (fastncmp("SPR_",word,4)) { p = word+4; for (i = 0; i < NUMSPRITES; i++) - if (!sprnames[i][4] && fastncmp(p,sprnames[i],4)) { + if (fastncmp(p,sprnames[i],4)) { // updating overridden sprnames is not implemented for soc parser, // so don't use cache if (mathlib) diff --git a/src/deh_soc.c b/src/deh_soc.c index 65db63ebb..6b90b6a86 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -443,14 +443,9 @@ void readfreeslots(MYFILE *f) for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) { if (used_spr[(i-SPR_FIRSTFREESLOT)/8] & (1<<(i%8))) - { - if (!sprnames[i][4] && memcmp(sprnames[i],word,4)==0) - sprnames[i][4] = (char)f->wad; continue; // Already allocated, next. - } // Found a free slot! strncpy(sprnames[i],word,4); - //sprnames[i][4] = 0; used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now. // Lua needs to update the value in _G if it exists LUA_UpdateSprName(word, i); @@ -4183,7 +4178,7 @@ spritenum_t get_sprite(const char *word) if (fastncmp("SPR_",word,4)) word += 4; // take off the SPR_ for (i = 0; i < NUMSPRITES; i++) - if (!sprnames[i][4] && memcmp(word,sprnames[i],4)==0) + if (memcmp(word,sprnames[i],4)==0) return i; deh_warning("Couldn't find sprite named 'SPR_%s'",word); return SPR_NULL; diff --git a/src/lua_script.c b/src/lua_script.c index b62fa675e..057899555 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -622,9 +622,6 @@ static inline boolean LUA_LoadFile(MYFILE *f, char *name) if (!gL) // Lua needs to be initialized LUA_ClearState(); - lua_pushinteger(gL, f->wad); - lua_setfield(gL, LUA_REGISTRYINDEX, "WAD"); - lua_pushcfunction(gL, LUA_GetErrorMessage); errorhandlerindex = lua_gettop(gL); diff --git a/src/r_things.c b/src/r_things.c index 76e680687..d56b473b8 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -480,9 +480,6 @@ void R_AddSpriteDefs(UINT16 wadnum) // for (i = 0; i < numsprites; i++) { - if (sprnames[i][4] && wadnum >= (UINT16)sprnames[i][4]) - continue; - if (R_AddSingleSpriteDef(sprnames[i], &sprites[i], wadnum, start, end)) { // if a new sprite was added (not just replaced) From 8073b8b3f0f85bd2201ed47f30e80d62d072dcf8 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 14 Mar 2024 20:20:12 +0100 Subject: [PATCH 02/32] Fix rare Lua bug when updating a SPR_ constant --- src/deh_lua.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index b73479263..9c9e62a69 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -740,7 +740,7 @@ void LUA_UpdateSprName(const char *name, lua_Integer value) if (!lua_isnil(gL, -1)) { - lua_pushstring(gL, name); + lua_pushstring(gL, fullname); lua_pushinteger(gL, value); lua_rawset(gL, LUA_GLOBALSINDEX); } From 092ac6643e924a8b4dab9e50482754ac6a944f08 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 14 Mar 2024 20:32:10 +0100 Subject: [PATCH 03/32] Allow sprite names with up to 64 characters --- src/deh_lua.c | 12 ++++++++---- src/deh_soc.c | 7 +++++-- src/hardware/hw_md2.c | 18 +++++++----------- src/info.c | 5 +++-- src/info.h | 5 +++-- src/r_picformats.c | 19 ++++++------------- src/r_things.c | 6 +++--- 7 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 9c9e62a69..0effe4fa7 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -60,13 +60,17 @@ static inline int lib_freeslot(lua_State *L) else if (fastcmp(type, "SPR")) { spritenum_t j; + + if (strlen(word) > MAXSPRITENAME) + return luaL_error(L, "Sprite name is longer than %d characters\n", strlen(word)); + for (j = SPR_FIRSTFREESLOT; j <= SPR_LASTFREESLOT; j++) { if (used_spr[(j-SPR_FIRSTFREESLOT)/8] & (1<<(j%8))) continue; // Already allocated, next. // Found a free slot! CONS_Printf("Sprite SPR_%s allocated.\n",word); - strncpy(sprnames[j],word,4); + strcpy(sprnames[j], word); used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now. // Lua needs to update the value in _G if it exists LUA_UpdateSprName(word, j); @@ -447,7 +451,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) else if (fastncmp("SPR_",word,4)) { p = word+4; for (i = 0; i < NUMSPRITES; i++) - if (fastncmp(p,sprnames[i],4)) { + if (fastcmp(p,sprnames[i])) { // updating overridden sprnames is not implemented for soc parser, // so don't use cache if (mathlib) @@ -729,12 +733,12 @@ static inline int lib_getenum(lua_State *L) // If a sprname has been "cached" to _G, update it to a new value. void LUA_UpdateSprName(const char *name, lua_Integer value) { - char fullname[9] = "SPR_XXXX"; + char fullname[4 + MAXSPRITENAME + 1] = "SPR_"; if (!gL) return; - strncpy(&fullname[4], name, 4); + strcpy(&fullname[4], name); lua_pushstring(gL, fullname); lua_rawget(gL, LUA_GLOBALSINDEX); diff --git a/src/deh_soc.c b/src/deh_soc.c index 6b90b6a86..fe43cd283 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -440,12 +440,15 @@ void readfreeslots(MYFILE *f) S_AddSoundFx(word, false, 0, false); else if (fastcmp(type, "SPR")) { + if (strlen(word) > MAXSPRITENAME) + I_Error("Sprite name is longer than %d characters\n", strlen(word)); + for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) { if (used_spr[(i-SPR_FIRSTFREESLOT)/8] & (1<<(i%8))) continue; // Already allocated, next. // Found a free slot! - strncpy(sprnames[i],word,4); + strcpy(sprnames[i], word); used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now. // Lua needs to update the value in _G if it exists LUA_UpdateSprName(word, i); @@ -4178,7 +4181,7 @@ spritenum_t get_sprite(const char *word) if (fastncmp("SPR_",word,4)) word += 4; // take off the SPR_ for (i = 0; i < NUMSPRITES; i++) - if (memcmp(word,sprnames[i],4)==0) + if (!strcmp(word, sprnames[i])) return i; deh_warning("Couldn't find sprite named 'SPR_%s'",word); return SPR_NULL; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 656fbc4a6..0bb8de851 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -571,19 +571,15 @@ void HWR_LoadModels(void) } // Add sprite models. - // Must be 4 characters long exactly. Otherwise, it's not a sprite name. - if (len == 4) + for (i = 0; i < numsprites; i++) { - for (i = 0; i < numsprites; i++) + if (stricmp(name, sprnames[i]) == 0) { - if (stricmp(name, sprnames[i]) == 0) - { - md2_models[i].scale = scale; - md2_models[i].offset = offset; - md2_models[i].found = true; - strcpy(md2_models[i].filename, filename); - goto modelfound; - } + md2_models[i].scale = scale; + md2_models[i].offset = offset; + md2_models[i].found = true; + strcpy(md2_models[i].filename, filename); + goto modelfound; } } diff --git a/src/info.c b/src/info.c index ab46cdbc7..9b33a57ab 100644 --- a/src/info.c +++ b/src/info.c @@ -26,9 +26,10 @@ #include "hardware/hw_light.h" #endif + // Hey, moron! If you change this table, don't forget about the sprite enum in info.h and the sprite lights in hw_light.c! // For the sake of constant merge conflicts, let's spread this out -char sprnames[NUMSPRITES + 1][5] = +char sprnames[NUMSPRITES + 1][MAXSPRITENAME + 1] = { "NULL", // invisible object "UNKN", @@ -525,7 +526,7 @@ char sprnames[NUMSPRITES + 1][5] = "GWLR", }; -char spr2names[NUMPLAYERSPRITES][5] = +char spr2names[NUMPLAYERSPRITES][MAXSPRITENAME + 1] = { "STND", "WAIT", diff --git a/src/info.h b/src/info.h index 9475b2302..0361f6428 100644 --- a/src/info.h +++ b/src/info.h @@ -575,6 +575,7 @@ extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION]; #define NUMMOBJFREESLOTS 1024 #define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS #define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8) +#define MAXSPRITENAME 64 // Hey, moron! If you change this table, don't forget about sprnames in info.c and the sprite lights in hw_light.c! typedef enum sprite @@ -4383,8 +4384,8 @@ typedef struct } state_t; extern state_t states[NUMSTATES]; -extern char sprnames[NUMSPRITES + 1][5]; -extern char spr2names[NUMPLAYERSPRITES][5]; +extern char sprnames[NUMSPRITES + 1][MAXSPRITENAME + 1]; +extern char spr2names[NUMPLAYERSPRITES][MAXSPRITENAME + 1]; extern playersprite_t spr2defaults[NUMPLAYERSPRITES]; extern state_t *astate; extern playersprite_t free_spr2; diff --git a/src/r_picformats.c b/src/r_picformats.c index e4a59f211..a75f15baf 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -1570,7 +1570,7 @@ static void R_ParseSpriteInfo(boolean spr2) spriteinfo_t *info; char *sprinfoToken; size_t sprinfoTokenLength; - char newSpriteName[5]; // no longer dynamically allocated + char newSpriteName[MAXSPRITENAME + 1]; // no longer dynamically allocated spritenum_t sprnum = NUMSPRITES; playersprite_t spr2num = NUMPLAYERSPRITES; INT32 i; @@ -1584,17 +1584,10 @@ 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 != 4) - { - I_Error("Error parsing SPRTINFO lump: Sprite name \"%s\" isn't 4 characters long",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 - } + 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) @@ -1603,7 +1596,7 @@ static void R_ParseSpriteInfo(boolean spr2) { if (i == NUMSPRITES) I_Error("Error parsing SPRTINFO lump: Unknown sprite name \"%s\"", newSpriteName); - if (!memcmp(newSpriteName,sprnames[i],4)) + if (!strcmp(newSpriteName, sprnames[i])) { sprnum = i; break; diff --git a/src/r_things.c b/src/r_things.c index d56b473b8..1a17def1d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -383,7 +383,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 { case SRF_NONE: // no rotations were found for that frame at all - I_Error("R_AddSingleSpriteDef: No patches found for %.4s frame %c", sprname, R_Frame2Char(frame)); + I_Error("R_AddSingleSpriteDef: No patches found for %s frame %c", sprname, R_Frame2Char(frame)); break; case SRF_SINGLE: @@ -393,7 +393,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 case SRF_2D: // both Left and Right rotations // we test to see whether the left and right slots are present if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR)) - I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations (L-R mode)", + I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations (L-R mode)", sprname, R_Frame2Char(frame)); break; @@ -404,7 +404,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 // we test the patch lump, or the id lump whatever // if it was not loaded the two are LUMPERROR if (sprtemp[frame].lumppat[rotation] == LUMPERROR) - I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations (1-%c mode)", + I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations (1-%c mode)", sprname, R_Frame2Char(frame), ((sprtemp[frame].rotate & SRF_3DGE) ? 'G' : '8')); break; } From 1c415749f74a2b13c4ca82d3af1ccd2ba92e95ff Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 15 Mar 2024 15:45:35 +0100 Subject: [PATCH 04/32] Refactor R_AddSpriteDefs --- src/r_things.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 1a17def1d..c9e1b7445 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -429,14 +429,10 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 return true; } -// -// Search for sprites replacements in a wad whose names are in namelist -// -void R_AddSpriteDefs(UINT16 wadnum) +static void AddShortSpriteDefs(UINT16 wadnum, size_t *ptr_spritesadded, size_t *ptr_framesadded) { - size_t i, addsprites = 0; + size_t i; UINT16 start, end; - char wadname[MAX_WADPATH]; // Find the sprites section in this resource file. switch (wadfiles[wadnum]->type) @@ -474,7 +470,6 @@ void R_AddSpriteDefs(UINT16 wadnum) return; } - // // scan through lumps, for each sprite, find all the sprite frames // @@ -483,15 +478,29 @@ void R_AddSpriteDefs(UINT16 wadnum) if (R_AddSingleSpriteDef(sprnames[i], &sprites[i], wadnum, start, end)) { // if a new sprite was added (not just replaced) - addsprites++; + (*ptr_spritesadded)++; #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "sprite %s set in pwad %d\n", sprnames[i], wadnum); #endif } } + *ptr_framesadded += end - start; +} + +// +// Search for sprites replacements in a wad whose names are in namelist +// +void R_AddSpriteDefs(UINT16 wadnum) +{ + char wadname[MAX_WADPATH]; + size_t spritesadded = 0; + size_t framesadded = 0; + + AddShortSpriteDefs(wadnum, &spritesadded, &framesadded); + nameonly(strcpy(wadname, wadfiles[wadnum]->filename)); - CONS_Printf(M_GetText("%s added %d frames in %s sprites\n"), wadname, end-start, sizeu1(addsprites)); + CONS_Printf(M_GetText("%s added %d frames in %s sprites\n"), wadname, framesadded, sizeu1(spritesadded)); } // From 837c3a7be36e32e6f44b6770f58c9bd2e0ea29fe Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 15 Mar 2024 20:06:21 +0100 Subject: [PATCH 05/32] Refactor R_AddSingleSpriteDef --- src/r_things.c | 62 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index c9e1b7445..42eea1e25 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -238,6 +238,40 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch sprtemp[frame].flip &= ~(1<= 64) + return false; + + if (namelen == 8) + { + *ret_frame2 = R_Char2Frame(name[6]); + *ret_rotation2 = R_Char2Rotation(name[7]); + if (*ret_frame2 >= 64) + return false; + } + else + { + *ret_frame2 = 255; + *ret_rotation2 = 255; + } + + return true; +} + // Install a single sprite, given its identifying name (4 chars) // // (originally part of R_AddSpriteDefs) @@ -254,8 +288,6 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump) { UINT16 l; - UINT8 frame; - UINT8 rotation; lumpinfo_t *lumpinfo; UINT16 numadded = 0; @@ -286,11 +318,12 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 { INT16 width, height; INT16 topoffset, leftoffset; + UINT8 frame, frame2; + UINT8 rotation, rotation2; - frame = R_Char2Frame(lumpinfo[l].name[4]); - rotation = R_Char2Rotation(lumpinfo[l].name[5]); + boolean good = GetFramesAndRotationsFromLumpName(lumpinfo[l].name, &frame, &rotation, &frame2, &rotation2); - if (frame >= 64 || rotation == 255) // Give an actual NAME error -_-... + if (!good) // Give an actual NAME error -_-... { CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); continue; @@ -322,19 +355,8 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 //---------------------------------------------------- R_InstallSpriteLump(wadnum, l, numspritelumps, frame, rotation, 0); - - if (lumpinfo[l].name[6]) - { - frame = R_Char2Frame(lumpinfo[l].name[6]); - rotation = R_Char2Rotation(lumpinfo[l].name[7]); - - if (frame >= 64 || rotation == 255) // Give an actual NAME error -_-... - { - CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); - continue; - } - R_InstallSpriteLump(wadnum, l, numspritelumps, frame, rotation, 1); - } + if (frame2 != 255) + R_InstallSpriteLump(wadnum, l, numspritelumps, frame2, rotation2, 1); if (++numspritelumps >= max_spritelumps) { @@ -377,7 +399,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 // // some checks to help development // - for (frame = 0; frame < maxframe; frame++) + for (UINT8 frame = 0; frame < maxframe; frame++) { switch (sprtemp[frame].rotate) { @@ -399,7 +421,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 default: // must have all 8/16 frames - rotation = ((sprtemp[frame].rotate & SRF_3DGE) ? 16 : 8); + UINT8 rotation = ((sprtemp[frame].rotate & SRF_3DGE) ? 16 : 8); while (rotation--) // we test the patch lump, or the id lump whatever // if it was not loaded the two are LUMPERROR From 33f176fd5bfa5ce0d0f915f705253c67c4a39dca Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 15 Mar 2024 20:15:38 +0100 Subject: [PATCH 06/32] Refactor R_AddSingleSpriteDef --- src/r_things.c | 77 +++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 42eea1e25..866d668f9 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -272,6 +272,47 @@ static boolean GetFramesAndRotationsFromLumpName( return true; } +// Some checks to help development +static void CheckFrame(const char *sprname) +{ + for (UINT8 frame = 0; frame < maxframe; frame++) + { + spriteframe_t *spriteframe = &sprtemp[frame]; + + switch (spriteframe->rotate) + { + case SRF_NONE: + // no rotations were found for that frame at all + I_Error("R_AddSingleSpriteDef: No patches found for %s frame %c", sprname, R_Frame2Char(frame)); + break; + + case SRF_SINGLE: + // only the first rotation is needed + break; + + case SRF_2D: // both Left and Right rotations + // we test to see whether the left and right slots are present + if ((spriteframe->lumppat[2] == LUMPERROR) || (spriteframe->lumppat[6] == LUMPERROR)) + I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations (L-R mode)", + sprname, R_Frame2Char(frame)); + break; + + default: + // must have all 8/16 frames + UINT8 rotation = ((spriteframe->rotate & SRF_3DGE) ? 16 : 8); + while (rotation--) + { + // we test the patch lump, or the id lump whatever + // if it was not loaded the two are LUMPERROR + if (spriteframe->lumppat[rotation] == LUMPERROR) + I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations (1-%c mode)", + sprname, R_Frame2Char(frame), ((spriteframe->rotate & SRF_3DGE) ? 'G' : '8')); + } + break; + } + } +} + // Install a single sprite, given its identifying name (4 chars) // // (originally part of R_AddSpriteDefs) @@ -396,41 +437,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 maxframe++; - // - // some checks to help development - // - for (UINT8 frame = 0; frame < maxframe; frame++) - { - switch (sprtemp[frame].rotate) - { - case SRF_NONE: - // no rotations were found for that frame at all - I_Error("R_AddSingleSpriteDef: No patches found for %s frame %c", sprname, R_Frame2Char(frame)); - break; - - case SRF_SINGLE: - // only the first rotation is needed - break; - - case SRF_2D: // both Left and Right rotations - // we test to see whether the left and right slots are present - if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR)) - I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations (L-R mode)", - sprname, R_Frame2Char(frame)); - break; - - default: - // must have all 8/16 frames - UINT8 rotation = ((sprtemp[frame].rotate & SRF_3DGE) ? 16 : 8); - while (rotation--) - // we test the patch lump, or the id lump whatever - // if it was not loaded the two are LUMPERROR - if (sprtemp[frame].lumppat[rotation] == LUMPERROR) - I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations (1-%c mode)", - sprname, R_Frame2Char(frame), ((sprtemp[frame].rotate & SRF_3DGE) ? 'G' : '8')); - break; - } - } + CheckFrame(sprname); // allocate space for the frames present and copy sprtemp to it if (spritedef->numframes && // has been allocated From 42c610af9cbc4fa36a41017a364fbf1a4b64d0a2 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 15 Mar 2024 21:02:41 +0100 Subject: [PATCH 07/32] Fix GetFramesAndRotationsFromShortLumpName --- src/r_things.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 866d668f9..4bfcaf7e0 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -253,14 +253,14 @@ static boolean GetFramesAndRotationsFromLumpName( *ret_frame = R_Char2Frame(name[4]); *ret_rotation = R_Char2Rotation(name[5]); - if (*ret_frame >= 64) + if (*ret_frame >= 64 || *ret_rotation == 255) return false; if (namelen == 8) { *ret_frame2 = R_Char2Frame(name[6]); *ret_rotation2 = R_Char2Rotation(name[7]); - if (*ret_frame2 >= 64) + if (*ret_frame2 >= 64 || *ret_rotation2 == 255) return false; } else From 99a9e5fcc9057ffeba39f7fef38b1b5154d4932c Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 15 Mar 2024 21:22:12 +0100 Subject: [PATCH 08/32] Add support for LongSprites/ folder --- src/r_skins.c | 4 +- src/r_things.c | 138 +++++++++++++++++++++++++++++++++++++++++-------- src/r_things.h | 4 +- src/w_wad.c | 41 +++++++++++++++ src/w_wad.h | 2 + 5 files changed, 165 insertions(+), 24 deletions(-) diff --git a/src/r_skins.c b/src/r_skins.c index 29a1556c0..d0d2eed62 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -625,7 +625,7 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski newlastlump++; // load all sprite sets we are aware of... for super! for (sprite2 = start_spr2; sprite2 < free_spr2; sprite2++) - R_AddSingleSpriteDef(spr2names[sprite2], &skin->super.sprites[sprite2], wadnum, newlastlump, *lastlump); + R_AddSingleSpriteDef(spr2names[sprite2], &skin->super.sprites[sprite2], wadnum, newlastlump, *lastlump, false); newlastlump--; *lastlump = newlastlump; // okay, make the normal sprite set loading end there @@ -633,7 +633,7 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski // load all sprite sets we are aware of... for normal stuff. for (sprite2 = start_spr2; sprite2 < free_spr2; sprite2++) - R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump); + R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump, false); if (skin->sprites[0].numframes == 0) CONS_Alert(CONS_ERROR, M_GetText("No frames found for sprite SPR2_%s\n"), spr2names[0]); diff --git a/src/r_things.c b/src/r_things.c index 4bfcaf7e0..317aa6c56 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -116,6 +116,14 @@ static INT32 drawsegs_xrange_count = 0; // // ========================================================================== +spritenum_t R_GetSpriteNumByName(const char *name) +{ + for (spritenum_t i = 0; i < NUMSPRITES; i++) + if (!strcmp(name, sprnames[i])) + return i; + return NUMSPRITES; +} + // // // @@ -147,9 +155,9 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch { // the lump should be used for all rotations if (sprtemp[frame].rotate == SRF_SINGLE) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has multiple rot = 0 lump\n", spritename, frame, cn); else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8/16 and L/R rotations into one debug message. - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has rotations and a rot = 0 lump\n", spritename, frame, cn); sprtemp[frame].rotate = SRF_SINGLE; for (r = 0; r < 16; r++) @@ -169,15 +177,15 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch if (sprtemp[frame].rotate == SRF_NONE) sprtemp[frame].rotate = SRF_SINGLE; else if (sprtemp[frame].rotate == SRF_SINGLE) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has L/R rotations and a rot = 0 lump\n", spritename, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has L/R rotations and a rot = 0 lump\n", spritename, frame, cn); else if (sprtemp[frame].rotate == SRF_3D) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has both L/R and 1-8 rotations\n", spritename, frame, cn); else if (sprtemp[frame].rotate == SRF_3DGE) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-G rotations\n", spritename, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has both L/R and 1-G rotations\n", spritename, frame, cn); else if ((sprtemp[frame].rotate & SRF_LEFT) && (rotation == ROT_L)) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple L rotations\n", spritename, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has multiple L rotations\n", spritename, frame, cn); else if ((sprtemp[frame].rotate & SRF_RIGHT) && (rotation == ROT_R)) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple R rotations\n", spritename, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has multiple R rotations\n", spritename, frame, cn); sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT); if ((sprtemp[frame].rotate & SRF_2D) == SRF_2D) @@ -204,9 +212,9 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch if (sprtemp[frame].rotate == SRF_NONE) sprtemp[frame].rotate = SRF_SINGLE; else if (sprtemp[frame].rotate == SRF_SINGLE) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has 1-8/G rotations and a rot = 0 lump\n", spritename, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has 1-8/G rotations and a rot = 0 lump\n", spritename, frame, cn); else if (sprtemp[frame].rotate & SRF_2D) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8/G rotations\n", spritename, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has both L/R and 1-8/G rotations\n", spritename, frame, cn); // make 0 based rotation--; @@ -226,7 +234,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch } if (sprtemp[frame].lumppat[rotation] != LUMPERROR) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, cr); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %d_%c (%c%c) has two lumps mapped to it\n", spritename, frame, cr, cn, cr); // lumppat & lumpid are the same for original Doom, but different // when using sprites in pwad : the lumppat points the new graphics @@ -238,7 +246,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch sprtemp[frame].flip &= ~(1< 4) + return false; + + char framepart[4 + 1]; // Max 9999 + strlcpy(framepart, name, framelen + 1); + + for (size_t i = 0; i < framelen; i++) + if (!isdigit(framepart[i])) + return false; + + *ret_frame = atoi(framepart); + *ret_rotation = R_Char2Rotation(*(underscore + 1)); + if (*ret_frame >= 64 || *ret_rotation == 255) + return false; + + *ret_frame2 = 255; + *ret_rotation2 = 255; + + return true; +} + // Some checks to help development static void CheckFrame(const char *sprname) { @@ -283,7 +325,7 @@ static void CheckFrame(const char *sprname) { case SRF_NONE: // no rotations were found for that frame at all - I_Error("R_AddSingleSpriteDef: No patches found for %s frame %c", sprname, R_Frame2Char(frame)); + I_Error("R_AddSingleSpriteDef: No patches found for %s frame %d (%c)", sprname, frame, R_Frame2Char(frame)); break; case SRF_SINGLE: @@ -293,8 +335,8 @@ static void CheckFrame(const char *sprname) case SRF_2D: // both Left and Right rotations // we test to see whether the left and right slots are present if ((spriteframe->lumppat[2] == LUMPERROR) || (spriteframe->lumppat[6] == LUMPERROR)) - I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations (L-R mode)", - sprname, R_Frame2Char(frame)); + I_Error("R_AddSingleSpriteDef: Sprite %s frame %d (%c) is missing rotations (L-R mode)", + sprname, frame, R_Frame2Char(frame)); break; default: @@ -305,8 +347,8 @@ static void CheckFrame(const char *sprname) // we test the patch lump, or the id lump whatever // if it was not loaded the two are LUMPERROR if (spriteframe->lumppat[rotation] == LUMPERROR) - I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations (1-%c mode)", - sprname, R_Frame2Char(frame), ((spriteframe->rotate & SRF_3DGE) ? 'G' : '8')); + I_Error("R_AddSingleSpriteDef: Sprite %s frame %d (%c) is missing rotations (1-%c mode)", + sprname, frame, R_Frame2Char(frame), ((spriteframe->rotate & SRF_3DGE) ? 'G' : '8')); } break; } @@ -317,16 +359,17 @@ static void CheckFrame(const char *sprname) // // (originally part of R_AddSpriteDefs) // -// Pass: name of sprite : 4 chars +// Pass: name of sprite // spritedef_t // wadnum : wad number, indexes wadfiles[], where patches // for frames are found // startlump : first lump to search for sprite frames // endlump : AFTER the last lump to search +// longname : whether to use long sprite names or 4-char names // // Returns true if the sprite was succesfully added // -boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump) +boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump, boolean longname) { UINT16 l; lumpinfo_t *lumpinfo; @@ -355,14 +398,18 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 for (l = startlump; l < endlump; l++) { - if (memcmp(lumpinfo[l].name,sprname,4)==0) + // For long sprites, the startlump-endlump range only includes + // relevant lumps, so no check needed in that case + if (longname || !memcmp(lumpinfo[l].name, sprname, 4)) { INT16 width, height; INT16 topoffset, leftoffset; UINT8 frame, frame2; UINT8 rotation, rotation2; - boolean good = GetFramesAndRotationsFromLumpName(lumpinfo[l].name, &frame, &rotation, &frame2, &rotation2); + boolean good = longname ? + GetFramesAndRotationsFromLongLumpName(lumpinfo[l].name, &frame, &rotation, &frame2, &rotation2) : + GetFramesAndRotationsFromShortLumpName(lumpinfo[l].name, &frame, &rotation, &frame2, &rotation2); if (!good) // Give an actual NAME error -_-... { @@ -504,7 +551,7 @@ static void AddShortSpriteDefs(UINT16 wadnum, size_t *ptr_spritesadded, size_t * // for (i = 0; i < numsprites; i++) { - if (R_AddSingleSpriteDef(sprnames[i], &sprites[i], wadnum, start, end)) + if (R_AddSingleSpriteDef(sprnames[i], &sprites[i], wadnum, start, end, false)) { // if a new sprite was added (not just replaced) (*ptr_spritesadded)++; @@ -517,6 +564,54 @@ static void AddShortSpriteDefs(UINT16 wadnum, size_t *ptr_spritesadded, size_t * *ptr_framesadded += end - start; } +static void AddLongSpriteDefs(UINT16 wadnum, size_t *ptr_spritesadded, size_t *ptr_framesadded) +{ + if (!W_FileHasFolders(wadfiles[wadnum])) + return; + + UINT16 start = W_CheckNumForFolderStartPK3("LongSprites/", wadnum, 0); + UINT16 end = W_CheckNumForFolderEndPK3("LongSprites/", wadnum, start); + + if (start == INT16_MAX || end == INT16_MAX || start >= end) + return; + + size_t lumpnum = start; + + while (lumpnum < end) + { + if (W_IsLumpFolder(wadnum, lumpnum)) + { + lumpnum++; + continue; + } + + UINT16 folderstart, folderend; + char *folderpath = W_GetLumpFolderPathPK3(wadnum, lumpnum); + folderstart = lumpnum; + folderend = W_CheckNumForFolderEndPK3(folderpath, wadnum, lumpnum); + Z_Free(folderpath); + + spritenum_t sprnum; + char *sprname = W_GetLumpFolderNamePK3(wadnum, lumpnum); + strupr(sprname); + sprnum = R_GetSpriteNumByName(sprname); + Z_Free(sprname); + + if (sprnum != NUMSPRITES && R_AddSingleSpriteDef(sprname, &sprites[sprnum], wadnum, folderstart, folderend, true)) + { + // A new sprite was added (not just replaced) + (*ptr_spritesadded)++; +#ifndef ZDEBUG + CONS_Debug(DBG_SETUP, "long sprite %s set in pwad %d\n", sprname, wadnum); +#endif + } + + lumpnum = folderend; + } + + *ptr_framesadded += end - start; +} + // // Search for sprites replacements in a wad whose names are in namelist // @@ -527,6 +622,7 @@ void R_AddSpriteDefs(UINT16 wadnum) size_t framesadded = 0; AddShortSpriteDefs(wadnum, &spritesadded, &framesadded); + AddLongSpriteDefs(wadnum, &spritesadded, &framesadded); nameonly(strcpy(wadname, wadfiles[wadnum]->filename)); CONS_Printf(M_GetText("%s added %d frames in %s sprites\n"), wadname, framesadded, sizeu1(spritesadded)); diff --git a/src/r_things.h b/src/r_things.h index f68d75a83..3daf55c42 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -27,7 +27,9 @@ #define FEETADJUST (4<lumpinfo[lump].fullname; + + const char *slash = strrchr(fullname, '/'); + INT32 pathlen = slash ? slash - fullname : 0; + + char *path = Z_Calloc(pathlen + 1, PU_STATIC, NULL); + strncpy(path, fullname, pathlen); + + return path; +} + +char *W_GetLumpFolderNamePK3(UINT16 wad, UINT16 lump) +{ + const char *fullname = wadfiles[wad]->lumpinfo[lump].fullname; + size_t start, end; + + INT32 i = strlen(fullname); + + i--; + while (i >= 0 && fullname[i] != '/') + i--; + if (i < 0) + return NULL; + end = i; + + i--; + while (i >= 0 && fullname[i] != '/') + i--; + if (i < 0) + return NULL; + start = i + 1; + + size_t namelen = end - start; + char *foldername = Z_Calloc(namelen + 1, PU_STATIC, NULL); + strncpy(foldername, fullname + start, namelen); + + return foldername; +} + void W_GetFolderLumpsPwad(const char *name, UINT16 wad, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps) { size_t name_length = strlen(name); diff --git a/src/w_wad.h b/src/w_wad.h index e043e4d62..80e0e32fd 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -180,6 +180,8 @@ UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlu UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump); +char *W_GetLumpFolderPathPK3(UINT16 wad, UINT16 lump); +char *W_GetLumpFolderNamePK3(UINT16 wad, UINT16 lump); void W_GetFolderLumpsPwad(const char *name, UINT16 wad, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps); void W_GetFolderLumps(const char *name, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps); From 178d29cf0c6002b31349739422a48fb0f7d81e7a Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 00:51:23 +0100 Subject: [PATCH 09/32] Allow up to 256 frames per sprite --- src/lua_infolib.c | 6 +++--- src/p_pspr.h | 2 +- src/r_defs.h | 2 ++ src/r_picformats.h | 2 +- src/r_things.c | 20 ++++++++++---------- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 0bcbcc5b9..cff72deb4 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -359,8 +359,8 @@ static int PopPivotTable(spriteinfo_t *info, lua_State *L, int stk) 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); + 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)) info->available = true; @@ -555,7 +555,7 @@ static int pivotlist_set(lua_State *L) static int pivotlist_num(lua_State *L) { - lua_pushinteger(L, 64); + lua_pushinteger(L, MAXFRAMENUM); return 1; } diff --git a/src/p_pspr.h b/src/p_pspr.h index be0d9f39e..5fb676763 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -35,7 +35,7 @@ #pragma interface #endif -/// \brief Frame flags: only the frame number - 0 to 256 (Frames from 0 to 63, Sprite2 number uses 0 to 127 plus FF_SPR2SUPER) +/// \brief Frame flags: only the frame number - 0 to 256 (Frames from 0 to 255, Sprite2 number uses 0 to 127 plus FF_SPR2SUPER) #define FF_FRAMEMASK 0xff /// \brief Frame flags - SPR2: Super sprite2 diff --git a/src/r_defs.h b/src/r_defs.h index cb94dd6e5..da4dd2d70 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -976,6 +976,8 @@ typedef struct #endif } spriteframe_t; +#define MAXFRAMENUM 256 + // // A sprite definition: a number of animation frames. // diff --git a/src/r_picformats.h b/src/r_picformats.h index 3ee9805d8..098f927a5 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -100,7 +100,7 @@ typedef struct typedef struct { - spriteframepivot_t pivot[64]; + spriteframepivot_t pivot[MAXFRAMENUM]; boolean available; } spriteinfo_t; diff --git a/src/r_things.c b/src/r_things.c index 317aa6c56..4e60e913f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -77,7 +77,7 @@ spriteinfo_t spriteinfo[NUMSPRITES]; spritedef_t *sprites; size_t numsprites; -static spriteframe_t sprtemp[64]; +static spriteframe_t sprtemp[MAXFRAMENUM]; static size_t maxframe; static const char *spritename; @@ -248,9 +248,9 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch static boolean GetFramesAndRotationsFromShortLumpName( const char *name, - UINT8 *ret_frame, + INT32 *ret_frame, UINT8 *ret_rotation, - UINT8 *ret_frame2, + INT32 *ret_frame2, UINT8 *ret_rotation2 ) { @@ -273,7 +273,7 @@ static boolean GetFramesAndRotationsFromShortLumpName( } else { - *ret_frame2 = 255; + *ret_frame2 = -1; *ret_rotation2 = 255; } @@ -282,9 +282,9 @@ static boolean GetFramesAndRotationsFromShortLumpName( static boolean GetFramesAndRotationsFromLongLumpName( const char *name, - UINT8 *ret_frame, + INT32 *ret_frame, UINT8 *ret_rotation, - UINT8 *ret_frame2, + INT32 *ret_frame2, UINT8 *ret_rotation2 ) { @@ -305,10 +305,10 @@ static boolean GetFramesAndRotationsFromLongLumpName( *ret_frame = atoi(framepart); *ret_rotation = R_Char2Rotation(*(underscore + 1)); - if (*ret_frame >= 64 || *ret_rotation == 255) + if (*ret_frame >= MAXFRAMENUM || *ret_rotation == 255) return false; - *ret_frame2 = 255; + *ret_frame2 = -1; *ret_rotation2 = 255; return true; @@ -404,7 +404,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 { INT16 width, height; INT16 topoffset, leftoffset; - UINT8 frame, frame2; + INT32 frame, frame2; UINT8 rotation, rotation2; boolean good = longname ? @@ -443,7 +443,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 //---------------------------------------------------- R_InstallSpriteLump(wadnum, l, numspritelumps, frame, rotation, 0); - if (frame2 != 255) + if (frame2 != -1) R_InstallSpriteLump(wadnum, l, numspritelumps, frame2, rotation2, 1); if (++numspritelumps >= max_spritelumps) From b3844a9ca5e2bff8e9b2832feca5c9943c73d5e5 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 16:14:52 +0100 Subject: [PATCH 10/32] Cleanup initfreeslots() --- src/deh_tables.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/deh_tables.h b/src/deh_tables.h index 42716f9b4..b71a2a23b 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -26,10 +26,10 @@ extern char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. #define initfreeslots() {\ - memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\ - memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\ - memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\ - memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ + memset(FREE_STATES, 0, sizeof(FREE_STATES));\ + memset(FREE_MOBJS, 0, sizeof(FREE_MOBJS));\ + memset(FREE_SKINCOLORS, 0, sizeof(FREE_SKINCOLORS));\ + memset(used_spr, 0, sizeof(used_spr));\ memset(actionsoverridden, LUA_REFNIL, sizeof(actionsoverridden));\ } From 45d54c38f74d3b8c681e73957e4fe4dfe1523792 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 16:26:33 +0100 Subject: [PATCH 11/32] Use bitarray_t for used_spr --- src/deh_lua.c | 4 ++-- src/deh_soc.c | 4 ++-- src/deh_tables.c | 2 +- src/deh_tables.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 0effe4fa7..3176f5d69 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -66,12 +66,12 @@ static inline int lib_freeslot(lua_State *L) for (j = SPR_FIRSTFREESLOT; j <= SPR_LASTFREESLOT; j++) { - if (used_spr[(j-SPR_FIRSTFREESLOT)/8] & (1<<(j%8))) + if (in_bit_array(used_spr, j - SPR_FIRSTFREESLOT)) continue; // Already allocated, next. // Found a free slot! CONS_Printf("Sprite SPR_%s allocated.\n",word); strcpy(sprnames[j], word); - used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now. + set_bit_array(used_spr, j - SPR_FIRSTFREESLOT); // Okay, this sprite slot has been named now. // Lua needs to update the value in _G if it exists LUA_UpdateSprName(word, j); lua_pushinteger(L, j); diff --git a/src/deh_soc.c b/src/deh_soc.c index fe43cd283..5e068313d 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -445,11 +445,11 @@ void readfreeslots(MYFILE *f) for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) { - if (used_spr[(i-SPR_FIRSTFREESLOT)/8] & (1<<(i%8))) + if (in_bit_array(used_spr, i - SPR_FIRSTFREESLOT)) continue; // Already allocated, next. // Found a free slot! strcpy(sprnames[i], word); - used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now. + set_bit_array(used_spr, i - SPR_FIRSTFREESLOT); // Okay, this sprite slot has been named now. // Lua needs to update the value in _G if it exists LUA_UpdateSprName(word, i); break; diff --git a/src/deh_tables.c b/src/deh_tables.c index ed401d68a..c7c7c6040 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -31,7 +31,7 @@ char *FREE_STATES[NUMSTATEFREESLOTS]; char *FREE_MOBJS[NUMMOBJFREESLOTS]; char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; -UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. +bitarray_t used_spr[BIT_ARRAY_SIZE(NUMSPRITEFREESLOTS)]; // Sprite freeslots in use const char NIGHTSGRADE_LIST[] = { 'F', // GRADE_F diff --git a/src/deh_tables.h b/src/deh_tables.h index b71a2a23b..b6986adff 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -23,7 +23,7 @@ extern char *FREE_STATES[NUMSTATEFREESLOTS]; extern char *FREE_MOBJS[NUMMOBJFREESLOTS]; extern char *FREE_SKINCOLORS[NUMCOLORFREESLOTS]; -extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway. +extern bitarray_t used_spr[BIT_ARRAY_SIZE(NUMSPRITEFREESLOTS)]; // Sprite freeslots in use #define initfreeslots() {\ memset(FREE_STATES, 0, sizeof(FREE_STATES));\ From a6b71826f91ee018cd9fdeef1b1f7a7e4bfadd30 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 17:00:59 +0100 Subject: [PATCH 12/32] Use R_GetSpriteNumByName everywhere --- src/deh_lua.c | 24 +++++++++++++----------- src/deh_soc.c | 6 +++--- src/lua_hudlib.c | 4 +--- src/lua_infolib.c | 25 +++++++++---------------- src/r_picformats.c | 13 +++---------- 5 files changed, 29 insertions(+), 43 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 3176f5d69..3d6d8b455 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -450,17 +450,19 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("SPR_",word,4)) { p = word+4; - for (i = 0; i < NUMSPRITES; i++) - if (fastcmp(p,sprnames[i])) { - // updating overridden sprnames is not implemented for soc parser, - // so don't use cache - if (mathlib) - lua_pushinteger(L, i); - else - CacheAndPushConstant(L, word, i); - return 1; - } - if (mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word); + i = R_GetSpriteNumByName(p); + if (i != NUMSPRITES) + { + // updating overridden sprnames is not implemented for soc parser, + // so don't use cache + if (mathlib) + lua_pushinteger(L, i); + else + CacheAndPushConstant(L, word, i); + return 1; + } + else if (mathlib) + return luaL_error(L, "sprite '%s' could not be found.\n", word); return 0; } else if (fastncmp("SPR2_",word,5)) { diff --git a/src/deh_soc.c b/src/deh_soc.c index 5e068313d..269598459 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -4180,9 +4180,9 @@ spritenum_t get_sprite(const char *word) return atoi(word); if (fastncmp("SPR_",word,4)) word += 4; // take off the SPR_ - for (i = 0; i < NUMSPRITES; i++) - if (!strcmp(word, sprnames[i])) - return i; + i = R_GetSpriteNumByName(word); + if (i != NUMSPRITES) + return i; deh_warning("Couldn't find sprite named 'SPR_%s'",word); return SPR_NULL; } diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index ddd6c6888..d6771f108 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -492,9 +492,7 @@ static int libd_getSpritePatch(lua_State *L) else if (lua_isstring(L, 1)) // sprite prefix name given, e.g. "THOK" { const char *name = lua_tostring(L, 1); - for (i = 0; i < NUMSPRITES; i++) - if (fastcmp(name, sprnames[i])) - break; + i = R_GetSpriteNumByName(name); if (i >= NUMSPRITES) return 0; } diff --git a/src/lua_infolib.c b/src/lua_infolib.c index cff72deb4..eeb1067a3 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -88,12 +88,12 @@ static int lib_getSprname(lua_State *L) else if (lua_isstring(L, 1)) { const char *name = lua_tostring(L, 1); - for (i = 0; i < NUMSPRITES; i++) - if (fastcmp(name, sprnames[i])) - { - lua_pushinteger(L, i); - return 1; - } + i = R_GetSpriteNumByName(name); + if (i != NUMSPRITES) + { + lua_pushinteger(L, i); + return 1; + } } return 0; } @@ -245,22 +245,15 @@ static int lib_getSpriteInfo(lua_State *L) if (lua_isstring(L, 1)) { const char *name = lua_tostring(L, 1); - INT32 spr; - for (spr = 0; spr < NUMSPRITES; spr++) - { - if (fastcmp(name, sprnames[spr])) - { - i = spr; - break; - } - } - if (i == NUMSPRITES) + INT32 spr = R_GetSpriteNumByName(name); + if (spr == NUMSPRITES) { char *check; i = strtol(name, &check, 10); if (check == name || *check != '\0') return luaL_error(L, "unknown sprite name %s", name); } + i = spr; } else i = luaL_checkinteger(L, 1); diff --git a/src/r_picformats.c b/src/r_picformats.c index a75f15baf..d71657021 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -1592,16 +1592,9 @@ static void R_ParseSpriteInfo(boolean spr2) if (!spr2) { - for (i = 0; i <= NUMSPRITES; i++) - { - if (i == NUMSPRITES) - I_Error("Error parsing SPRTINFO lump: Unknown sprite name \"%s\"", newSpriteName); - if (!strcmp(newSpriteName, sprnames[i])) - { - sprnum = i; - break; - } - } + sprnum = R_GetSpriteNumByName(newSpriteName); + if (sprnum == NUMSPRITES) + I_Error("Error parsing SPRTINFO lump: Unknown sprite name \"%s\"", newSpriteName); } else { From de8a4bb3e147d99640ad3ba2afd40d90cc96233d Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 17:21:35 +0100 Subject: [PATCH 13/32] Fix compiler warnings --- src/deh_lua.c | 2 +- src/deh_soc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 3d6d8b455..0d5f48ce1 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -62,7 +62,7 @@ static inline int lib_freeslot(lua_State *L) spritenum_t j; if (strlen(word) > MAXSPRITENAME) - return luaL_error(L, "Sprite name is longer than %d characters\n", strlen(word)); + return luaL_error(L, "Sprite name is longer than %s characters\n", sizeu1(strlen(word))); for (j = SPR_FIRSTFREESLOT; j <= SPR_LASTFREESLOT; j++) { diff --git a/src/deh_soc.c b/src/deh_soc.c index 269598459..6e4c087d5 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -441,7 +441,7 @@ void readfreeslots(MYFILE *f) else if (fastcmp(type, "SPR")) { if (strlen(word) > MAXSPRITENAME) - I_Error("Sprite name is longer than %d characters\n", strlen(word)); + I_Error("Sprite name is longer than %s characters\n", sizeu1(strlen(word))); for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) { From a0c253f81e2a1a102be95409629748c82fc658bd Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 17:49:34 +0100 Subject: [PATCH 14/32] Fix invalid syntax --- src/r_things.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 4e60e913f..d21f9465e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -340,15 +340,17 @@ static void CheckFrame(const char *sprname) break; default: - // must have all 8/16 frames - UINT8 rotation = ((spriteframe->rotate & SRF_3DGE) ? 16 : 8); - while (rotation--) { - // we test the patch lump, or the id lump whatever - // if it was not loaded the two are LUMPERROR - if (spriteframe->lumppat[rotation] == LUMPERROR) - I_Error("R_AddSingleSpriteDef: Sprite %s frame %d (%c) is missing rotations (1-%c mode)", - sprname, frame, R_Frame2Char(frame), ((spriteframe->rotate & SRF_3DGE) ? 'G' : '8')); + // must have all 8/16 frames + UINT8 rotation = ((spriteframe->rotate & SRF_3DGE) ? 16 : 8); + while (rotation--) + { + // we test the patch lump, or the id lump whatever + // if it was not loaded the two are LUMPERROR + if (spriteframe->lumppat[rotation] == LUMPERROR) + I_Error("R_AddSingleSpriteDef: Sprite %s frame %d (%c) is missing rotations (1-%c mode)", + sprname, frame, R_Frame2Char(frame), ((spriteframe->rotate & SRF_3DGE) ? 'G' : '8')); + } } break; } From 9b6c642345e67bbdf6cc790c70182f5b7edeb2eb Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 18:13:43 +0100 Subject: [PATCH 15/32] Fix infinite loop --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index d21f9465e..795f7cb5c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -317,7 +317,7 @@ static boolean GetFramesAndRotationsFromLongLumpName( // Some checks to help development static void CheckFrame(const char *sprname) { - for (UINT8 frame = 0; frame < maxframe; frame++) + for (UINT32 frame = 0; frame < maxframe; frame++) { spriteframe_t *spriteframe = &sprtemp[frame]; From dc3436df78046343bfe8f6448a9e7f06c396b347 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 18:54:10 +0100 Subject: [PATCH 16/32] Fix compiler warnings --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 795f7cb5c..53d54765e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -627,7 +627,7 @@ void R_AddSpriteDefs(UINT16 wadnum) AddLongSpriteDefs(wadnum, &spritesadded, &framesadded); nameonly(strcpy(wadname, wadfiles[wadnum]->filename)); - CONS_Printf(M_GetText("%s added %d frames in %s sprites\n"), wadname, framesadded, sizeu1(spritesadded)); + CONS_Printf(M_GetText("%s added %s frames in %s sprites\n"), wadname, sizeu1(framesadded), sizeu1(spritesadded)); } // From 737156659252c2ed6adc20bfd4eaa0e4b959b7d4 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 19:35:56 +0100 Subject: [PATCH 17/32] Fix error message for too long sprite names --- src/deh_lua.c | 2 +- src/deh_soc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 0d5f48ce1..64fb52fc7 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -62,7 +62,7 @@ static inline int lib_freeslot(lua_State *L) spritenum_t j; if (strlen(word) > MAXSPRITENAME) - return luaL_error(L, "Sprite name is longer than %s characters\n", sizeu1(strlen(word))); + return luaL_error(L, "Sprite name is longer than %d characters\n", MAXSPRITENAME); for (j = SPR_FIRSTFREESLOT; j <= SPR_LASTFREESLOT; j++) { diff --git a/src/deh_soc.c b/src/deh_soc.c index 6e4c087d5..d1643fd4e 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -441,7 +441,7 @@ void readfreeslots(MYFILE *f) else if (fastcmp(type, "SPR")) { if (strlen(word) > MAXSPRITENAME) - I_Error("Sprite name is longer than %s characters\n", sizeu1(strlen(word))); + I_Error("Sprite name is longer than %d characters\n", MAXSPRITENAME); for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++) { From 4ebda932bb784c24a728c5d6a91e384d5c4f6261 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 16 Mar 2024 19:36:18 +0100 Subject: [PATCH 18/32] Cleanup --- src/r_things.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 53d54765e..64f40c62e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -137,9 +137,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch char cn = R_Frame2Char(frame), cr = R_Rotation2Char(rotation); // for debugging INT32 r; - lumpnum_t lumppat = wad; - lumppat <<= 16; - lumppat += lump; + lumpnum_t lumppat = (wad << 16) + lump; if (maxframe ==(size_t)-1 || frame > maxframe) maxframe = frame; From 761a97292783b0f25ca7ab988c7a29a6145afb6e Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 17 Mar 2024 00:27:19 +0100 Subject: [PATCH 19/32] Fix R_AddSingleSpriteDef for short sprite names --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 64f40c62e..ba3bf736a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -400,7 +400,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 { // For long sprites, the startlump-endlump range only includes // relevant lumps, so no check needed in that case - if (longname || !memcmp(lumpinfo[l].name, sprname, 4)) + if (longname || (strlen(sprname) == 4 && !memcmp(lumpinfo[l].name, sprname, 4))) { INT16 width, height; INT16 topoffset, leftoffset; From 0f6f6afb447f895cb6a8dbb721f0fc08c81199b6 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 17 Mar 2024 00:28:25 +0100 Subject: [PATCH 20/32] Fix sprite and frame addition logging --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index ba3bf736a..d317c0bd8 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -625,7 +625,7 @@ void R_AddSpriteDefs(UINT16 wadnum) AddLongSpriteDefs(wadnum, &spritesadded, &framesadded); nameonly(strcpy(wadname, wadfiles[wadnum]->filename)); - CONS_Printf(M_GetText("%s added %s frames in %s sprites\n"), wadname, sizeu1(framesadded), sizeu1(spritesadded)); + CONS_Printf(M_GetText("%s added %s frames in %s sprites\n"), wadname, sizeu1(framesadded), sizeu2(spritesadded)); } // From f6cb5d563cce3cf4576ffdc5f50dfe352b249c8b Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 17 Mar 2024 00:40:29 +0100 Subject: [PATCH 21/32] Only log sprite and frame additions when at least one was added --- src/r_things.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index d317c0bd8..bda754dba 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -624,8 +624,11 @@ void R_AddSpriteDefs(UINT16 wadnum) AddShortSpriteDefs(wadnum, &spritesadded, &framesadded); AddLongSpriteDefs(wadnum, &spritesadded, &framesadded); - nameonly(strcpy(wadname, wadfiles[wadnum]->filename)); - CONS_Printf(M_GetText("%s added %s frames in %s sprites\n"), wadname, sizeu1(framesadded), sizeu2(spritesadded)); + if (spritesadded || framesadded) + { + nameonly(strcpy(wadname, wadfiles[wadnum]->filename)); + CONS_Printf(M_GetText("%s added %s frames in %s sprites\n"), wadname, sizeu1(framesadded), sizeu2(spritesadded)); + } } // From 0e57d70b95dd9f035d8eb261d38689d9901090a5 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 17 Mar 2024 00:41:38 +0100 Subject: [PATCH 22/32] Automatically mirror long sprites for missing rotations --- src/r_things.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/r_things.c b/src/r_things.c index bda754dba..5c4698e5d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -312,6 +312,38 @@ static boolean GetFramesAndRotationsFromLongLumpName( return true; } +static UINT8 GetOppositeRotation(UINT8 rotation, UINT8 flags) +{ + if (flags & ~SRF_3DMASK) + I_Error("GetOppositeRotation: rotation type not supported"); + + UINT8 numrotations = (flags == SRF_3D) ? 8 : 16; + return (rotation == 1) ? 1 : numrotations + 2 - rotation; +} + +static void MirrorMissingRotations(void) +{ + for (UINT32 framenum = 0; framenum < maxframe; framenum++) + { + spriteframe_t *frame = &sprtemp[framenum]; + + if (!(frame->rotate & SRF_3DMASK)) + continue; + + UINT8 numrotations = frame->rotate == SRF_3D ? 8 : 16; + + for (UINT8 rotation = 1; rotation <= numrotations; rotation++) + { + if (frame->lumppat[rotation - 1] != LUMPERROR) + continue; + + UINT8 baserotation = GetOppositeRotation(rotation, frame->rotate); + UINT32 lumpnum = frame->lumppat[baserotation - 1]; + R_InstallSpriteLump(WADFILENUM(lumpnum), LUMPNUM(lumpnum), frame->lumpid[baserotation], framenum, rotation, 1); + } + } +} + // Some checks to help development static void CheckFrame(const char *sprname) { @@ -484,6 +516,9 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 maxframe++; + if (longname) + MirrorMissingRotations(); + CheckFrame(sprname); // allocate space for the frames present and copy sprtemp to it From 49fa45039e7bc3f1964269363c2f770a4fa71ff6 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 20 Mar 2024 18:06:19 +0100 Subject: [PATCH 23/32] Fix error report when some frames are missing --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 5c4698e5d..534ce7368 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -327,7 +327,7 @@ static void MirrorMissingRotations(void) { spriteframe_t *frame = &sprtemp[framenum]; - if (!(frame->rotate & SRF_3DMASK)) + if (frame->rotate == SRF_NONE || !(frame->rotate & SRF_3DMASK)) continue; UINT8 numrotations = frame->rotate == SRF_3D ? 8 : 16; From f406e9bbb57c89e3d6c58710dcbb91316664bda5 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 3 Apr 2024 20:39:53 +0200 Subject: [PATCH 24/32] Throw a Lua error when R_Frame2Char is called with a frame number without character representation --- src/lua_baselib.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9e4eebeb0..f6b8f462b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3030,6 +3030,9 @@ static int lib_rFrame2Char(lua_State *L) //HUDSAFE c[0] = R_Frame2Char(ch); + if (c[0] == '\xFF') + return luaL_error(L, "frame %u cannot be represented by a character", ch); + c[1] = 0; lua_pushstring(L, c); From 32a3683e07bb31db1cf8a3f22446a85fea69649e Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 3 Apr 2024 22:06:03 +0200 Subject: [PATCH 25/32] Fix error message when a patch is missing --- src/r_things.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 534ce7368..7d9701105 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -355,7 +355,10 @@ static void CheckFrame(const char *sprname) { case SRF_NONE: // no rotations were found for that frame at all - I_Error("R_AddSingleSpriteDef: No patches found for %s frame %d (%c)", sprname, frame, R_Frame2Char(frame)); + if (frame < 64) + I_Error("R_AddSingleSpriteDef: No patches found for %s frame %d (%c)", sprname, frame, R_Frame2Char(frame)); + else + I_Error("R_AddSingleSpriteDef: No patches found for %s frame %d", sprname, frame); break; case SRF_SINGLE: From eaf0ba6658328c3b8fd4f6e8a00caa59c09a9673 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 3 Apr 2024 22:07:59 +0200 Subject: [PATCH 26/32] Error out when a sprite definition contains a subfolder --- src/r_things.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/r_things.c b/src/r_things.c index 7d9701105..076777597 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -433,6 +433,9 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 for (l = startlump; l < endlump; l++) { + if (W_IsLumpFolder(wadnum, l)) + I_Error("R_AddSingleSpriteDef: all frame lumps for a sprite should be contained inside a single folder\n"); + // For long sprites, the startlump-endlump range only includes // relevant lumps, so no check needed in that case if (longname || (strlen(sprname) == 4 && !memcmp(lumpinfo[l].name, sprname, 4))) From 245a82112fda2b782d0e12b5fc41e7c3959135e8 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 3 Apr 2024 22:39:58 +0200 Subject: [PATCH 27/32] Make rotation optional for long sprites --- src/r_things.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 076777597..102efdec9 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -287,10 +287,8 @@ static boolean GetFramesAndRotationsFromLongLumpName( ) { const char *underscore = strchr(name, '_'); - if (!underscore) - return false; - size_t framelen = underscore - name; + size_t framelen = underscore ? (size_t)(underscore - name) : strlen(name); if (framelen < 1 || framelen > 4) return false; @@ -302,7 +300,7 @@ static boolean GetFramesAndRotationsFromLongLumpName( return false; *ret_frame = atoi(framepart); - *ret_rotation = R_Char2Rotation(*(underscore + 1)); + *ret_rotation = underscore ? R_Char2Rotation(*(underscore + 1)) : 0; if (*ret_frame >= MAXFRAMENUM || *ret_rotation == 255) return false; From 22106ef8b118e2062d76e2ca100645fbf3027a50 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 3 Apr 2024 23:24:54 +0200 Subject: [PATCH 28/32] Fix short sprite names triggering an error --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 102efdec9..90d1bf646 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -431,7 +431,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 for (l = startlump; l < endlump; l++) { - if (W_IsLumpFolder(wadnum, l)) + if (longname && W_IsLumpFolder(wadnum, l)) I_Error("R_AddSingleSpriteDef: all frame lumps for a sprite should be contained inside a single folder\n"); // For long sprites, the startlump-endlump range only includes From 8a6b5d7c0f863753290c8630ae7c143432f7188c Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 4 Apr 2024 00:06:33 +0200 Subject: [PATCH 29/32] Support setting two frames per lump for long sprites --- src/r_things.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 90d1bf646..004e0a6c2 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -278,17 +278,20 @@ static boolean GetFramesAndRotationsFromShortLumpName( return true; } -static boolean GetFramesAndRotationsFromLongLumpName( +static boolean GetSingleFrameAndRotation( const char *name, + size_t len, INT32 *ret_frame, - UINT8 *ret_rotation, - INT32 *ret_frame2, - UINT8 *ret_rotation2 + UINT8 *ret_rotation ) { const char *underscore = strchr(name, '_'); - size_t framelen = underscore ? (size_t)(underscore - name) : strlen(name); + // Found but past the part of the name we are parsing + if ((size_t)(underscore - name) >= len) + underscore = NULL; + + size_t framelen = underscore ? (size_t)(underscore - name) : len; if (framelen < 1 || framelen > 4) return false; @@ -304,8 +307,36 @@ static boolean GetFramesAndRotationsFromLongLumpName( if (*ret_frame >= MAXFRAMENUM || *ret_rotation == 255) return false; - *ret_frame2 = -1; - *ret_rotation2 = 255; + return true; +} + +static boolean GetFramesAndRotationsFromLongLumpName( + const char *name, + INT32 *ret_frame, + UINT8 *ret_rotation, + INT32 *ret_frame2, + UINT8 *ret_rotation2 +) +{ + const char *plus = strchr(name, '+'); + + if (plus) + { + size_t len1 = plus - name; + + if (!GetSingleFrameAndRotation(name, len1, ret_frame, ret_rotation)) + return false; + if (!GetSingleFrameAndRotation(plus + 1, strlen(name) - len1 - 1, ret_frame2, ret_rotation2)) + return false; + } + else + { + if (!GetSingleFrameAndRotation(name, strlen(name), ret_frame, ret_rotation)) + return false; + + *ret_frame2 = -1; + *ret_rotation2 = 255; + } return true; } @@ -444,7 +475,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 UINT8 rotation, rotation2; boolean good = longname ? - GetFramesAndRotationsFromLongLumpName(lumpinfo[l].name, &frame, &rotation, &frame2, &rotation2) : + GetFramesAndRotationsFromLongLumpName(lumpinfo[l].longname, &frame, &rotation, &frame2, &rotation2) : GetFramesAndRotationsFromShortLumpName(lumpinfo[l].name, &frame, &rotation, &frame2, &rotation2); if (!good) // Give an actual NAME error -_-... From a1649186ce44fe99a6811a9ba41c50b0da240ba2 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 5 Apr 2024 17:31:42 +0200 Subject: [PATCH 30/32] Fix some error messages --- src/r_things.c | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 004e0a6c2..3bda42a4a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -136,6 +136,12 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch { char cn = R_Frame2Char(frame), cr = R_Rotation2Char(rotation); // for debugging + char framedescription[256]; + if (cn != '\xFF') + sprintf(framedescription, "%s frame %d (%c)", spritename, frame, cn); + else + sprintf(framedescription, "%s frame %d", spritename, frame); + INT32 r; lumpnum_t lumppat = (wad << 16) + lump; @@ -153,9 +159,9 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch { // the lump should be used for all rotations if (sprtemp[frame].rotate == SRF_SINGLE) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has multiple rot = 0 lump\n", spritename, frame, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s has multiple rot = 0 lump\n", framedescription); else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8/16 and L/R rotations into one debug message. - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has rotations and a rot = 0 lump\n", spritename, frame, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s has rotations and a rot = 0 lump\n", framedescription); sprtemp[frame].rotate = SRF_SINGLE; for (r = 0; r < 16; r++) @@ -175,15 +181,15 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch if (sprtemp[frame].rotate == SRF_NONE) sprtemp[frame].rotate = SRF_SINGLE; else if (sprtemp[frame].rotate == SRF_SINGLE) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has L/R rotations and a rot = 0 lump\n", spritename, frame, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s has L/R rotations and a rot = 0 lump\n", framedescription); else if (sprtemp[frame].rotate == SRF_3D) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has both L/R and 1-8 rotations\n", spritename, frame, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s has both L/R and 1-8 rotations\n", framedescription); else if (sprtemp[frame].rotate == SRF_3DGE) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has both L/R and 1-G rotations\n", spritename, frame, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s has both L/R and 1-G rotations\n", framedescription); else if ((sprtemp[frame].rotate & SRF_LEFT) && (rotation == ROT_L)) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has multiple L rotations\n", spritename, frame, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s has multiple L rotations\n", framedescription); else if ((sprtemp[frame].rotate & SRF_RIGHT) && (rotation == ROT_R)) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has multiple R rotations\n", spritename, frame, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s has multiple R rotations\n", framedescription); sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT); if ((sprtemp[frame].rotate & SRF_2D) == SRF_2D) @@ -210,9 +216,9 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch if (sprtemp[frame].rotate == SRF_NONE) sprtemp[frame].rotate = SRF_SINGLE; else if (sprtemp[frame].rotate == SRF_SINGLE) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has 1-8/G rotations and a rot = 0 lump\n", spritename, frame, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s has 1-8/G rotations and a rot = 0 lump\n", framedescription); else if (sprtemp[frame].rotate & SRF_2D) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %d (%c) has both L/R and 1-8/G rotations\n", spritename, frame, cn); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s has both L/R and 1-8/G rotations\n", framedescription); // make 0 based rotation--; @@ -232,7 +238,12 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch } if (sprtemp[frame].lumppat[rotation] != LUMPERROR) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %d_%c (%c%c) has two lumps mapped to it\n", spritename, frame, cr, cn, cr); + { + if (cn != '\xFF') + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %d_%c (%c%c) has two lumps mapped to it\n", spritename, frame, cr, cn, cr); + else + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %d_%c has two lumps mapped to it\n", spritename, frame, cr); + } // lumppat & lumpid are the same for original Doom, but different // when using sprites in pwad : the lumppat points the new graphics @@ -380,14 +391,17 @@ static void CheckFrame(const char *sprname) { spriteframe_t *spriteframe = &sprtemp[frame]; + char framedescription[256]; + if (frame < 64) + sprintf(framedescription, "%s frame %d (%c)", sprname, frame, R_Frame2Char(frame)); + else + sprintf(framedescription, "%s frame %d", sprname, frame); + switch (spriteframe->rotate) { case SRF_NONE: // no rotations were found for that frame at all - if (frame < 64) - I_Error("R_AddSingleSpriteDef: No patches found for %s frame %d (%c)", sprname, frame, R_Frame2Char(frame)); - else - I_Error("R_AddSingleSpriteDef: No patches found for %s frame %d", sprname, frame); + I_Error("R_AddSingleSpriteDef: No patches found for %s", framedescription); break; case SRF_SINGLE: @@ -397,8 +411,8 @@ static void CheckFrame(const char *sprname) case SRF_2D: // both Left and Right rotations // we test to see whether the left and right slots are present if ((spriteframe->lumppat[2] == LUMPERROR) || (spriteframe->lumppat[6] == LUMPERROR)) - I_Error("R_AddSingleSpriteDef: Sprite %s frame %d (%c) is missing rotations (L-R mode)", - sprname, frame, R_Frame2Char(frame)); + I_Error("R_AddSingleSpriteDef: Sprite %s is missing rotations (L-R mode)", + framedescription); break; default: @@ -410,8 +424,8 @@ static void CheckFrame(const char *sprname) // we test the patch lump, or the id lump whatever // if it was not loaded the two are LUMPERROR if (spriteframe->lumppat[rotation] == LUMPERROR) - I_Error("R_AddSingleSpriteDef: Sprite %s frame %d (%c) is missing rotations (1-%c mode)", - sprname, frame, R_Frame2Char(frame), ((spriteframe->rotate & SRF_3DGE) ? 'G' : '8')); + I_Error("R_AddSingleSpriteDef: Sprite %s is missing rotations (1-%c mode)", + framedescription, ((spriteframe->rotate & SRF_3DGE) ? 'G' : '8')); } } break; From 4a9462761a434665fa071e46c8e98afe2ead3d33 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 5 Apr 2024 19:10:15 +0200 Subject: [PATCH 31/32] Fix early free --- src/r_things.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 3bda42a4a..c46d81624 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -679,7 +679,6 @@ static void AddLongSpriteDefs(UINT16 wadnum, size_t *ptr_spritesadded, size_t *p char *sprname = W_GetLumpFolderNamePK3(wadnum, lumpnum); strupr(sprname); sprnum = R_GetSpriteNumByName(sprname); - Z_Free(sprname); if (sprnum != NUMSPRITES && R_AddSingleSpriteDef(sprname, &sprites[sprnum], wadnum, folderstart, folderend, true)) { @@ -690,6 +689,8 @@ static void AddLongSpriteDefs(UINT16 wadnum, size_t *ptr_spritesadded, size_t *p #endif } + Z_Free(sprname); + lumpnum = folderend; } From 829a12e7ac778a37ed09bdbfd699118903414b28 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 7 Apr 2024 18:35:58 +0200 Subject: [PATCH 32/32] Fix SOC freeslotting including trailing spaces in constant names --- src/deh_soc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index d1643fd4e..dda3b2ef4 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -405,7 +405,6 @@ void readfreeslots(MYFILE *f) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *word,*type; - char *tmp; int i; do @@ -415,10 +414,13 @@ void readfreeslots(MYFILE *f) if (s[0] == '\n') break; - tmp = strchr(s, '#'); - if (tmp) - *tmp = '\0'; - if (s == tmp) + char *hashtag = strchr(s, '#'); + char *space = strchr(s, ' '); + if (hashtag) + *hashtag = '\0'; + if (space) + *space = '\0'; + if (s == hashtag || s == space) continue; // Skip comment lines, but don't break. type = strtok(s, "_");