From 14e8ac702f29b413ea9e9af3f7ff672ffab017f9 Mon Sep 17 00:00:00 2001
From: Yukita Mayako <catgirl@goddess.moe>
Date: Sat, 31 Oct 2015 14:45:42 -0400
Subject: [PATCH] Added freeslots for SPR2.

Make sure your MAINCFG / LUA lump comes _before_ the S_SKIN section.
---
 src/dehacked.c    | 45 ++++++++++++++++++++++++++++++++++++++++-----
 src/info.c        |  1 +
 src/info.h        |  5 ++++-
 src/lua_infolib.c |  6 +++---
 src/r_things.c    |  2 +-
 5 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/src/dehacked.c b/src/dehacked.c
index 0ba054f07c..a350254949 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -671,6 +671,22 @@ static void readfreeslots(MYFILE *f)
 						break;
 					}
 			}
+			else if (fastcmp(type, "SPR2_"))
+			{
+				// Search if we already have an SPR2 by that name...
+				for (i = SPR_FIRSTFREESLOT; i < free_spr2; i++)
+					if (memcmp(spr2names[i],word,4) == 0)
+						break;
+				// We found it? (Two mods using the same SPR2 name?) Then don't allocate another one.
+				if (i != free_spr2)
+					continue;
+				// Copy in the spr2 name and increment free_spr2.
+				if (free_spr2 < NUMPLAYERSPRITES) {
+					strncpy(spr2names[free_spr2],word,4);
+					spr2names[free_spr2++][4] = 0;
+				} else
+					CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
+			}
 			else
 				deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);
 		}
@@ -8292,7 +8308,7 @@ static inline int lib_freeslot(lua_State *L)
 				lua_pushinteger(L, sfx);
 				r++;
 			} else
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n");
 		}
 		else if (fastcmp(type, "SPR"))
 		{
@@ -8319,7 +8335,7 @@ static inline int lib_freeslot(lua_State *L)
 				break;
 			}
 			if (j > SPR_LASTFREESLOT)
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n");
 		}
 		else if (fastcmp(type, "S"))
 		{
@@ -8334,7 +8350,7 @@ static inline int lib_freeslot(lua_State *L)
 					break;
 				}
 			if (i == NUMSTATEFREESLOTS)
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n");
 		}
 		else if (fastcmp(type, "MT"))
 		{
@@ -8349,7 +8365,26 @@ static inline int lib_freeslot(lua_State *L)
 					break;
 				}
 			if (i == NUMMOBJFREESLOTS)
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n");
+		}
+		else if (fastcmp(type, "SPR2"))
+		{
+			// Search if we already have an SPR2 by that name...
+			enum playersprite i;
+			for (i = SPR_FIRSTFREESLOT; i < free_spr2; i++)
+				if (memcmp(spr2names[i],word,4) == 0)
+					break;
+			// We don't, so allocate a new one.
+			if (i == free_spr2) {
+				if (free_spr2 < NUMPLAYERSPRITES)
+				{
+					CONS_Printf("Sprite SPR2_%s allocated.\n",word);
+					strncpy(spr2names[free_spr2],word,4);
+					spr2names[free_spr2++][4] = 0;
+				} else
+					CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
+			}
+			r++;
 		}
 		Z_Free(s);
 		lua_remove(L, 1);
@@ -8516,7 +8551,7 @@ static inline int lib_getenum(lua_State *L)
 	}
 	else if (fastncmp("SPR2_",word,4)) {
 		p = word+5;
-		for (i = 0; i < NUMPLAYERSPRITES; i++)
+		for (i = 0; i < free_spr2; i++)
 			if (!spr2names[i][4])
 			{
 				// special 3-char cases, e.g. SPR2_RUN
diff --git a/src/info.c b/src/info.c
index 8d7c249adf..d6ccab1f98 100644
--- a/src/info.c
+++ b/src/info.c
@@ -99,6 +99,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
 	"SRID",
 	"SFLT"
 };
+enum playersprite free_spr2 = SPR2_FIRSTFREESLOT;
 
 // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
 state_t states[NUMSTATES] =
diff --git a/src/info.h b/src/info.h
index e313526b92..67602b3017 100644
--- a/src/info.h
+++ b/src/info.h
@@ -618,6 +618,8 @@ enum playersprite
 	SPR2_SRID,
 	SPR2_SFLT,
 
+	SPR2_FIRSTFREESLOT,
+	SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
 	NUMPLAYERSPRITES
 };
 
@@ -3528,8 +3530,9 @@ typedef struct
 
 extern state_t states[NUMSTATES];
 extern char sprnames[NUMSPRITES + 1][5];
-char spr2names[NUMPLAYERSPRITES][5];
+extern char spr2names[NUMPLAYERSPRITES][5];
 extern state_t *astate;
+extern enum playersprite free_spr2;
 
 typedef enum mobj_type
 {
diff --git a/src/lua_infolib.c b/src/lua_infolib.c
index a983bb0029..1925ffd355 100644
--- a/src/lua_infolib.c
+++ b/src/lua_infolib.c
@@ -105,7 +105,7 @@ static int lib_getSpr2name(lua_State *L)
 	if (lua_isnumber(L, 1))
 	{
 		i = lua_tonumber(L, 1);
-		if (i > NUMPLAYERSPRITES)
+		if (i >= free_spr2)
 			return 0;
 		lua_pushlstring(L, spr2names[i], 4);
 		return 1;
@@ -113,7 +113,7 @@ static int lib_getSpr2name(lua_State *L)
 	else if (lua_isstring(L, 1))
 	{
 		const char *name = lua_tostring(L, 1);
-		for (i = 0; i < NUMPLAYERSPRITES; i++)
+		for (i = 0; i < free_spr2; i++)
 			if (fastcmp(name, spr2names[i]))
 			{
 				lua_pushinteger(L, i);
@@ -125,7 +125,7 @@ static int lib_getSpr2name(lua_State *L)
 
 static int lib_spr2namelen(lua_State *L)
 {
-	lua_pushinteger(L, NUMPLAYERSPRITES);
+	lua_pushinteger(L, free_spr2);
 	return 1;
 }
 
diff --git a/src/r_things.c b/src/r_things.c
index 60fbad1af0..461ac978c9 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -2671,7 +2671,7 @@ next_token:
 			if (z < lastlump) lastlump = z;
 
 			// load all sprite sets we are aware of.
-			for (sprite2 = 0; sprite2 < NUMPLAYERSPRITES; sprite2++)
+			for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
 				R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, lump, lastlump);
 		}
 
-- 
GitLab