From a7e99ab5cfd2acb306542c448dfb6af9140e4d28 Mon Sep 17 00:00:00 2001
From: Nev3r <apophycens@gmail.com>
Date: Sun, 12 Apr 2020 11:56:36 +0200
Subject: [PATCH] Added static multitag read and storage on mapload.

---
 src/CMakeLists.txt |  2 ++
 src/Makefile       |  1 +
 src/doomdata.h     |  3 +++
 src/p_setup.c      | 50 +++++++++++++++++++++++++++++++++++++++++++++-
 src/r_defs.h       |  4 ++++
 src/taglist.c      |  8 ++++++++
 src/taglist.h      | 14 +++++++++++++
 7 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 src/taglist.c
 create mode 100644 src/taglist.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b0a593bb1..7f18407ac 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -164,6 +164,7 @@ set(SRB2_CORE_GAME_SOURCES
 	p_telept.c
 	p_tick.c
 	p_user.c
+	taglist.c
 
 	p_local.h
 	p_maputl.h
@@ -175,6 +176,7 @@ set(SRB2_CORE_GAME_SOURCES
 	p_slopes.h
 	p_spec.h
 	p_tick.h
+	taglist.h
 )
 
 if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
diff --git a/src/Makefile b/src/Makefile
index fdf9c78b7..d27883563 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -474,6 +474,7 @@ OBJS:=$(i_main_o) \
 		$(OBJDIR)/r_patch.o \
 		$(OBJDIR)/r_portal.o \
 		$(OBJDIR)/screen.o   \
+		$(OBJDIR)/taglist.o  \
 		$(OBJDIR)/v_video.o  \
 		$(OBJDIR)/s_sound.o  \
 		$(OBJDIR)/sounds.o   \
diff --git a/src/doomdata.h b/src/doomdata.h
index d9bfb43b1..884c043a4 100644
--- a/src/doomdata.h
+++ b/src/doomdata.h
@@ -23,6 +23,8 @@
 // Some global defines, that configure the game.
 #include "doomdef.h"
 
+#include "taglist.h"
+
 //
 // Map level types.
 // The following data structures define the persistent format
@@ -204,6 +206,7 @@ typedef struct
 	INT16 z;
 	UINT8 extrainfo;
 	INT16 tag;
+	taglist_t tags;
 	struct mobj_s *mobj;
 } mapthing_t;
 
diff --git a/src/p_setup.c b/src/p_setup.c
index 871fb14fe..e4658d742 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -81,6 +81,8 @@
 
 #include "fastcmp.h" // textmap parsing
 
+#include "taglist.h"
+
 //
 // Map MD5, calculated on level load.
 // Sent to clients in PT_SERVERINFO.
@@ -935,6 +937,8 @@ static void P_LoadSectors(UINT8 *data)
 		ss->lightlevel = SHORT(ms->lightlevel);
 		ss->special = SHORT(ms->special);
 		ss->tag = SHORT(ms->tag);
+		if (ss->tag)
+			Tag_Add(&ss->tags, ss->tag);
 
 		ss->floor_xoffs = ss->floor_yoffs = 0;
 		ss->ceiling_xoffs = ss->ceiling_yoffs = 0;
@@ -1049,6 +1053,8 @@ static void P_LoadLinedefs(UINT8 *data)
 		ld->flags = SHORT(mld->flags);
 		ld->special = SHORT(mld->special);
 		ld->tag = SHORT(mld->tag);
+		if (ld->tag)
+			Tag_Add(&ld->tags, ld->tag);
 		memset(ld->args, 0, NUMLINEARGS*sizeof(*ld->args));
 		memset(ld->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ld->stringargs));
 		ld->alpha = FRACUNIT;
@@ -1398,7 +1404,21 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
 	else if (fastcmp(param, "special"))
 		sectors[i].special = atol(val);
 	else if (fastcmp(param, "id"))
+	{
 		sectors[i].tag = atol(val);
+		if (sectors[i].tag)
+			Tag_Add(&sectors[i].tags, sectors[i].tag);
+	}
+	else if (fastcmp(param, "moreids"))
+	{
+		char* id = val;
+		while (id)
+		{
+			Tag_Add(&sectors[i].tags, atol(id));
+			if ((id = strchr(id, ' ')))
+				id++;
+		}
+	}
 	else if (fastcmp(param, "xpanningfloor"))
 		sectors[i].floor_xoffs = FLOAT_TO_FIXED(atof(val));
 	else if (fastcmp(param, "ypanningfloor"))
@@ -1434,7 +1454,21 @@ static void ParseTextmapSidedefParameter(UINT32 i, char *param, char *val)
 static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val)
 {
 	if (fastcmp(param, "id"))
+	{
 		lines[i].tag = atol(val);
+		if (lines[i].tag)
+			Tag_Add(&lines[i].tags, lines[i].tag);
+	}
+	else if (fastcmp(param, "moreids"))
+	{
+		char* id = val;
+		while (id)
+		{
+			Tag_Add(&lines[i].tags, atol(id));
+			if ((id = strchr(id, ' ')))
+				id++;
+		}
+	}
 	else if (fastcmp(param, "special"))
 		lines[i].special = atol(val);
 	else if (fastcmp(param, "v1"))
@@ -1501,8 +1535,22 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val)
 static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
 {
 	if (fastcmp(param, "id"))
+	{
 		mapthings[i].tag = atol(val);
-	if (fastcmp(param, "x"))
+		if (mapthings[i].tag)
+			Tag_Add(&mapthings[i].tags, mapthings[i].tag);
+	}
+	else if (fastcmp(param, "moreids"))
+	{
+		char* id = val;
+		while (id)
+		{
+			Tag_Add(&mapthings[i].tags, atol(id));
+			if ((id = strchr(id, ' ')))
+				id++;
+		}
+	}
+	else if (fastcmp(param, "x"))
 		mapthings[i].x = atol(val);
 	else if (fastcmp(param, "y"))
 		mapthings[i].y = atol(val);
diff --git a/src/r_defs.h b/src/r_defs.h
index 943f54761..ab35b2055 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -30,6 +30,8 @@
 
 #define POLYOBJECTS
 
+#include "taglist.h"
+
 //
 // ClipWallSegment
 // Clips the given range of columns
@@ -290,6 +292,7 @@ typedef struct sector_s
 	INT16 lightlevel;
 	INT16 special;
 	UINT16 tag;
+	taglist_t tags;
 	INT32 nexttag, firsttag; // for fast tag searches
 
 	// origin for any sounds played by the sector
@@ -413,6 +416,7 @@ typedef struct line_s
 	INT16 flags;
 	INT16 special;
 	INT16 tag;
+	taglist_t tags;
 	INT32 args[NUMLINEARGS];
 	char *stringargs[NUMLINESTRINGARGS];
 
diff --git a/src/taglist.c b/src/taglist.c
new file mode 100644
index 000000000..9090d4e0b
--- /dev/null
+++ b/src/taglist.c
@@ -0,0 +1,8 @@
+#include "taglist.h"
+#include "z_zone.h"
+
+void Tag_Add (taglist_t* list, const UINT16 tag)
+{
+	list->tags = Z_Realloc(list->tags, (list->count + 1) * sizeof(list->tags), PU_LEVEL, NULL);
+	list->tags[list->count++] = tag;
+}
diff --git a/src/taglist.h b/src/taglist.h
new file mode 100644
index 000000000..744918d7c
--- /dev/null
+++ b/src/taglist.h
@@ -0,0 +1,14 @@
+#include "doomtype.h"
+
+#ifndef __R_TAGLIST__
+#define __R_TAGLIST__
+
+/// Multitag list.
+typedef struct
+{
+	UINT16* tags;
+	UINT16 count;
+} taglist_t;
+
+void Tag_Add (taglist_t* list, const UINT16 tag);
+#endif //__R_TAGLIST__
-- 
GitLab